[Genie95] #4. React์—์„œ Webamp๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ๋ชจ๋‹ฌ ์—†์ด ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

2025. 3. 27. 14:12ยทGenie

๐Ÿ”ฅ ๋ฌธ์ œ ์ƒํ™ฉ: Webamp๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์‹คํ–‰๋˜๊ณ  ๋นˆ ๋ชจ๋‹ฌ์ด ๋œจ๋Š” ๋ฌธ์ œ

 

React์—์„œ Webamp๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์ค‘๋ณต ์‹คํ–‰๋˜๊ฑฐ๋‚˜ ๋นˆ ๋ชจ๋‹ฌ์ด ๋œจ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Webamp๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜๊ณ , Taskbar์—์„œ ์ง์ ‘ Webamp๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.


์ „์—ญ ๋ณ€์ˆ˜๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

์ „์—ญ ๋ณ€์ˆ˜(Global Variable)๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. React์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋“ค์ด ์ดˆ๊ธฐํ™”๋˜์ง€๋งŒ, ์ „์—ญ ๋ณ€์ˆ˜๋Š” ๊ฐ’์ด ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ง€์—ญ ๋ณ€์ˆ˜ vs. ์ „์—ญ ๋ณ€์ˆ˜

๋ณ€์ˆ˜ ์œ„์น˜ ํŠน์ง• Webamp ์ ์šฉ
์ง€์—ญ ๋ณ€์ˆ˜ (์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€ ๋ณ€์ˆ˜) ํ•จ์ˆ˜ ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋จ startWebamp() ํ˜ธ์ถœ ์‹œ Webamp๊ฐ€ ๊ณ„์† ์ƒˆ๋กœ ์ƒ์„ฑ๋จ
์ „์—ญ ๋ณ€์ˆ˜ (let webampInstance) ํ•œ ๋ฒˆ ์ƒ์„ฑ๋˜๋ฉด ๊ณ„์† ์œ ์ง€๋จ ์ด๋ฏธ ์‹คํ–‰๋œ Webamp๊ฐ€ ์žˆ์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ

 

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: Webamp๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

startWebamp.js์—์„œ Webamp๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์ €์žฅ

import Webamp from "webamp";

let webampInstance = null; // โœ… Webamp ์ธ์Šคํ„ด์Šค๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์ €์žฅ

const startWebamp = () => {
    if (!Webamp.browserIsSupported()) return;

    // โœ… ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ Webamp๊ฐ€ ์žˆ๋‹ค๋ฉด ์ข…๋ฃŒ ํ›„ ์ƒˆ๋กœ ์ƒ์„ฑ
    if (webampInstance) {
        try {
            const audio = webampInstance.getMediaElement();
            if (audio) {
                audio.pause(); // โœ… ๋จผ์ € ์˜ค๋””์˜ค ์ •์ง€
                audio.src = ""; // โœ… ๊ธฐ์กด ์˜ค๋””์˜ค ์ŠคํŠธ๋ฆผ์„ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”
            }
            webampInstance.dispose(); // โœ… ์ŠคํŠธ๋ฆผ์„ ์™„์ „ํžˆ ๋‹ซ์€ ํ›„ Webamp ์ข…๋ฃŒ
            webampInstance = null;
        } catch (error) {
            console.warn("Webamp dispose error:", error);
        }
    }

    // โœ… ์ƒˆ๋กœ์šด Webamp ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
    webampInstance = new Webamp({
        initialTracks: [
            {
                metadata: { artist: "AJR", title: "Bang!" },
                url: "/AJR-bang!.mp3", // โœ… ํŒŒ์ผ ๊ฒฝ๋กœ ํ™•์ธ ํ•„์š”
            },
        ],
    });

    webampInstance.onClose(() => {
        try {
            const audio = webampInstance.getMediaElement();
            if (audio) {
                audio.pause();
                audio.src = ""; // โœ… ์˜ค๋””์˜ค ์ŠคํŠธ๋ฆผ์„ ์ดˆ๊ธฐํ™”
            }
            webampInstance.dispose();
            webampInstance = null;
        } catch (error) {
            console.warn("Webamp dispose error:", error);
        }
    });

    webampInstance.renderWhenReady(document.getElementById("winamp-container"));
};

export { startWebamp };
  • Webamp๊ฐ€ ํ•˜๋‚˜๋งŒ ์‹คํ–‰๋˜๋„๋ก ์ˆ˜์ •
  • Webamp๋ฅผ ๋‹ซ์œผ๋ฉด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ null๋กœ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
  • ๊ธฐ์กด Webamp๊ฐ€ ์žˆ๋‹ค๋ฉด dispose() ํ›„ ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ๋กœ ์ƒ์„ฑ

ModalContext.js์—์„œ media ๋ชจ๋‹ฌ ์‚ญ์ œ

Taskbar์—์„œ ์ง์ ‘ Webamp๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด, ModalContext์—์„œ media ๊ด€๋ จ ์ƒํƒœ๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const ModalProvider = ({ children }) => {
    const [modals, setModals] = useState({
        contact: false, // โœ… media ๊ด€๋ จ ์ƒํƒœ ์ œ๊ฑฐ
    });

    return (
        <ModalContext.Provider value={{ modals, openModal, closeModal }}>
            {children}
        </ModalContext.Provider>
    );
};
  • ์ด์ œ ๋นˆ ๋ชจ๋‹ฌ์ด ๋œจ์ง€ ์•Š์Œ
  • ๋ชจ๋‹ฌ ์—†์ด Webamp๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝ

Taskbar.js์—์„œ Webamp ์ง์ ‘ ์‹คํ–‰ํ•˜๊ธฐ

import React, { useState } from "react";
import { TaskBar as React95Taskbar, List } from "@react95/core";
import { Cdplayer107 } from "@react95/icons";
import Player from "../components/Player"; // โœ… Player ์ง์ ‘ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

const CustomTaskbar = () => {
    const [showPlayer, setShowPlayer] = useState(false); // โœ… Player ์ƒํƒœ ๊ด€๋ฆฌ

    return (
        <>
            <React95Taskbar
                list={
                    <List>
                        <List.Item icon={<Cdplayer107 variant="32x32_4" />} onClick={() => setShowPlayer(true)}>
                            Media
                        </List.Item>
                    </List>
                }
            />

            {/* โœ… Taskbar์—์„œ ์ง์ ‘ Player ์‹คํ–‰ */}
            {showPlayer && <Player closeModal={() => setShowPlayer(false)} />}
        </>
    );
};

export default CustomTaskbar;
  • Taskbar์—์„œ openModal("media") ๋Œ€์‹  setShowPlayer(true)๋กœ ์ง์ ‘ ์‹คํ–‰
  • Webamp๋ฅผ ModalContext๊ฐ€ ์•„๋‹Œ Taskbar์—์„œ ์ง์ ‘ ๊ด€๋ฆฌ

Player.js์—์„œ Modal์„ ์ œ๊ฑฐํ•˜๊ณ  Webamp๋งŒ ์‹คํ–‰

import React, { useEffect } from "react";
import { startWebamp } from "../utils/startWebamp";

const Player = ({ closeModal }) => {
    useEffect(() => {
        startWebamp(); // โœ… Webamp ์‹คํ–‰
    }, []);

    return (
        <div id="winamp-container" style={{ width: "100%", height: "100%" }}></div>
    );
};

export default Player;
  • Modal์„ ๊ฐ์‹ธ์ง€ ์•Š๊ณ  Webamp๋งŒ ์‹คํ–‰
  • ๋นˆ ๋ชจ๋‹ฌ ์—†์ด Webamp๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ๋ณ€๊ฒฝ

๐ŸŽฏ ์ตœ์ข… ์ •๋ฆฌ

๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
โœ… Webamp๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์‹คํ–‰๋จ Webamp๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜(let webampInstance)๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ํ•œ ๊ฐœ๋งŒ ์‹คํ–‰
โœ… Taskbar์—์„œ Media ํด๋ฆญ ์‹œ ๋นˆ ๋ชจ๋‹ฌ์ด ๋œธ ModalContext.js์—์„œ media ๊ด€๋ จ ์ƒํƒœ๋ฅผ ์‚ญ์ œ
โœ… Taskbar์—์„œ Webamp๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์Œ openModal("media")๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  setShowPlayer(true)๋กœ ์ง์ ‘ ์‹คํ–‰
โœ… Player.js์—์„œ ๋ชจ๋‹ฌ ์—†์ด Webamp๋งŒ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์Œ Modal์„ ๊ฐ์‹ธ์ง€ ์•Š๊ณ  Webamp๋งŒ ์‹คํ–‰๋˜๋„๋ก ์ˆ˜์ •

 

 

์ด์ œ Taskbar์—์„œ Webamp๊ฐ€ ์ค‘๋ณต ์—†์ด ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๊ณ , ๋นˆ ๋ชจ๋‹ฌ ์—†์ด ์ •์ƒ ์ž‘๋™๋ฉ๋‹ˆ๋‹ค!

 
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋™์ผ์กฐ๊ฑด (์ƒˆ์ฐฝ์—ด๋ฆผ)

'Genie' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

์ˆ˜์˜๊ณผ ๊ฐœ๋ฐœ  (0) 2025.03.04
๋ธ”๋กœ๊ทธ๋ฅผ ์—ด๋ฉฐ  (0) 2024.11.22
'Genie' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • ์ˆ˜์˜๊ณผ ๊ฐœ๋ฐœ
  • ๋ธ”๋กœ๊ทธ๋ฅผ ์—ด๋ฉฐ
Genie Choi ์ง€๋‹ˆ ์ดˆ์ด
Genie Choi ์ง€๋‹ˆ ์ดˆ์ด
  • Genie Choi ์ง€๋‹ˆ ์ดˆ์ด
    Genie World
    Genie Choi ์ง€๋‹ˆ ์ดˆ์ด
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (27)
      • Genie (3)
      • Projects (6)
      • Up-to-date learning (0)
      • App Development (10)
        • React Native (1)
        • Swift (9)
      • Marketing Tool (1)
        • Mobile Measurement Platform (1)
        • CRM Marketing (0)
      • Linux (5)
      • AWS (2)
        • EC2 (1)
        • Route 53 (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ํ‹ฐ์Šคํ† ๋ฆฌ์ฑŒ๋ฆฐ์ง€
    ์˜ค๋ธ”์™„
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.1
Genie Choi ์ง€๋‹ˆ ์ดˆ์ด
[Genie95] #4. React์—์„œ Webamp๋ฅผ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ๋ชจ๋‹ฌ ์—†์ด ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”