{"id":731,"date":"2023-06-23T16:39:59","date_gmt":"2023-06-23T07:39:59","guid":{"rendered":"https:\/\/blog.mydepot.kr\/?p=731"},"modified":"2023-06-23T16:40:00","modified_gmt":"2023-06-23T07:40:00","slug":"javascript-mp3%ed%8c%8c%ec%9d%bc-%ea%b8%b0%eb%b3%b8-%ec%9e%ac%ec%83%9d%ea%b8%b0-%ec%a3%bc%ed%8c%8c%ec%88%98-%eb%b6%84%ec%84%9d","status":"publish","type":"post","link":"https:\/\/blog.mydepot.kr\/?p=731","title":{"rendered":"[javascript] mp3\ud30c\uc77c \uae30\ubcf8 \uc7ac\uc0dd\uae30 + \uc8fc\ud30c\uc218 \ubd84\uc11d"},"content":{"rendered":"\n<p>\uae30\ubcf8\uc801\uc778 \uc7ac\uc0dd\uae30 \uae30\ub2a5\uc5d0 \ucd94\uac00\uc801\uc73c\ub85c 1\ucd08\ub9c8\ub2e4 \uc8fc\ud30c\uc218 \ubd84\uc11d \uac12\uc744 \ucf58\uc194\uc5d0 \ucd9c\ub825\ud558\ub294 \ucf54\ub4dc\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc0c1\ud669\uc5d0 \uc54c\ub9de\uac8c \uc218\uc815\ud574\uc11c \uc0ac\uc6a9\ud558\uba74 \ub418\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n\n&lt;head&gt;\n      &lt;meta charset=&quot;UTF-8&quot;&gt;\n      &lt;title&gt;MP3 \ubd84\uc11d \ubc0f \uc7ac\uc0dd&lt;\/title&gt;\n      &lt;style&gt;\n            #progressBar {\n                  background-color: black;\n            }\n\n            #progress {\n                  display: inline-block;\n                  height: 10px;\n                  background-color: red;\n            }\n      &lt;\/style&gt;\n&lt;\/head&gt;\n\n&lt;body&gt;\n      &lt;button id=&quot;playPauseButton&quot;&gt;\uc7ac\uc0dd\/\uc77c\uc2dc\uc815\uc9c0&lt;\/button&gt;\n      &lt;button id=&quot;stopButton&quot;&gt;\uc815\uc9c0&lt;\/button&gt;\n      &lt;button id=&quot;muteButton&quot;&gt;\uc74c\uc18c\uac70&lt;\/button&gt;\n      &lt;input type=&quot;range&quot; id=&quot;volumeControl&quot; min=&quot;0&quot; max=&quot;1&quot; step=&quot;0.1&quot; value=&quot;1&quot;&gt;\n      &lt;div id=&quot;progressBar&quot;&gt;\n            &lt;div id=&quot;progress&quot;&gt;&lt;\/div&gt;\n      &lt;\/div&gt;\n      &lt;div id=&quot;currentTime&quot;&gt;&lt;\/div&gt;\n      &lt;div id=&quot;totalTime&quot;&gt;&lt;\/div&gt;\n\n      &lt;script&gt;\n            \/\/ MP3 \ud30c\uc77c\uacfc \uc774\ubbf8\uc9c0 \ud30c\uc77c\uc758 \uacbd\ub85c\n            const mp3Url = &#039;\/1.mp3&#039;;\n            \/\/ const imageUrl = &#039;\/1.png&#039;;\n\n            \/\/ \uc624\ub514\uc624 \uc694\uc18c \uc0dd\uc131\n            const audio = new Audio(mp3Url);\n            audio.controls = true;\n\n            \/\/ \ubd84\uc11d \ubc84\ud2bc \ud65c\uc131\ud654\n            audio.addEventListener(&#039;canplaythrough&#039;, () =&gt; {\n                  console.log(&#039;MP3 \ud30c\uc77c \ub85c\ub4dc \uc644\ub8cc&#039;);\n                  document.getElementById(&#039;playPauseButton&#039;).disabled = false;\n            });\n\n            \/\/ \uc7ac\uc0dd\/\uc77c\uc2dc\uc815\uc9c0 \ubc84\ud2bc \ud074\ub9ad \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec\n            const playPauseButton = document.getElementById(&#039;playPauseButton&#039;);\n            playPauseButton.addEventListener(&#039;click&#039;, function () {\n                  if (audio.paused) {\n                        audio.play();\n                        playPauseButton.textContent = &#039;\uc77c\uc2dc\uc815\uc9c0&#039;;\n                  } else {\n                        audio.pause();\n                        playPauseButton.textContent = &#039;\uc7ac\uc0dd&#039;;\n                  }\n            });\n\n            \/\/ \uc815\uc9c0 \ubc84\ud2bc \ud074\ub9ad \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec\n            const stopButton = document.getElementById(&#039;stopButton&#039;);\n            stopButton.addEventListener(&#039;click&#039;, function () {\n                  audio.pause();\n                  audio.currentTime = 0;\n                  playPauseButton.textContent = &#039;\uc7ac\uc0dd&#039;;\n            });\n\n            \/\/ \uc74c\uc18c\uac70 \ud1a0\uae00 \ubc84\ud2bc \ud074\ub9ad \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec\n            const muteButton = document.getElementById(&#039;muteButton&#039;);\n            muteButton.addEventListener(&#039;click&#039;, function () {\n                  audio.muted = !audio.muted;\n                  muteButton.textContent = audio.muted ? &#039;\uc74c\uc18c\uac70 \ud574\uc81c&#039; : &#039;\uc74c\uc18c\uac70&#039;;\n            });\n\n            \/\/ \ubcfc\ub968 \ucee8\ud2b8\ub864 \ubcc0\uacbd \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec\n            const volumeControl = document.getElementById(&#039;volumeControl&#039;);\n            volumeControl.addEventListener(&#039;input&#039;, function () {\n                  audio.volume = parseFloat(volumeControl.value);\n            });\n\n            \/\/ \uc7ac\uc0dd\ubc14 \uc5c5\ub370\uc774\ud2b8 \ud568\uc218\n            function updateProgressBar() {\n                  const progress = (audio.currentTime \/ audio.duration) * 100;\n                  document.getElementById(&#039;progress&#039;).style.width = progress + &#039;%&#039;;\n                  document.getElementById(&#039;currentTime&#039;).textContent = formatTime(audio.currentTime);\n            }\n\n            \/\/ \ud604\uc7ac \uc7ac\uc0dd \uc2dc\uac04 \ud3ec\ub9f7 \ud568\uc218\n            function formatTime(time) {\n                  const minutes = Math.floor(time \/ 60);\n                  const seconds = Math.floor(time % 60);\n                  return `${minutes}:${seconds &lt; 10 ? &#039;0&#039; : &#039;&#039;}${seconds}`;\n            }\n\n            \/\/ \uc804\uccb4 \uc7ac\uc0dd \uc2dc\uac04 \ud45c\uc2dc\n            const totalTime = document.getElementById(&#039;totalTime&#039;);\n            audio.addEventListener(&#039;canplay&#039;, () =&gt; {\n                  totalTime.textContent = formatTime(audio.duration);\n            });\n\n            \/\/ \uc7ac\uc0dd\ubc14 \ud074\ub9ad \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec\n            const progressBar = document.getElementById(&#039;progressBar&#039;);\n            progressBar.addEventListener(&#039;click&#039;, function (event) {\n                  const progressWidth = progressBar.clientWidth;\n                  const clickX = event.pageX - progressBar.offsetLeft;\n                  const seekTime = (clickX \/ progressWidth) * audio.duration;\n                  audio.currentTime = seekTime;\n            });\n\n            \/\/ \uc624\ub514\uc624 \ucee8\ud14d\uc2a4\ud2b8 \uc0dd\uc131\n            const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n\n            \/\/ \uc624\ub514\uc624 \uc18c\uc2a4 \ub178\ub4dc \uc0dd\uc131\n            const audioSourceNode = audioCtx.createMediaElementSource(audio);\n\n            \/\/ \uc624\ub514\uc624 \ubd84\uc11d\uae30 \uc0dd\uc131\n            const analyser = audioCtx.createAnalyser();\n            analyser.fftSize = Math.pow(2, 6);\n            const bufferLength = analyser.frequencyBinCount;\n            const dataArray = new Uint8Array(bufferLength);\n\n            \/\/ \uc624\ub514\uc624 \ub178\ub4dc \ub124\ud2b8\uc6cc\ud06c \uc124\uc815\n            audioSourceNode.connect(analyser);\n            analyser.connect(audioCtx.destination);\n\n            \/\/ \ub370\uc774\ud130 \ub85c\uae45 \ubc0f \uc7ac\uc0dd\ubc14 \uc5c5\ub370\uc774\ud2b8\n            setInterval(() =&gt; {\n                  analyser.getByteFrequencyData(dataArray);\n                  console.log(&#039;\ubd84\uc11d \ub370\uc774\ud130(\ubc30\uc5f4)&#039;, Array.from(dataArray));\n\n                  const frequencyData = {}; \/\/ \ubd84\uc11d \ub370\uc774\ud130\ub97c \ub2f4\uc744 \uac1d\uccb4\n\n                  for (let i = 0; i &lt; bufferLength; i++) {\n                        const frequency = i * (audioCtx.sampleRate \/ analyser.fftSize); \/\/ \uc778\ub371\uc2a4\ub97c \uc2e4\uc81c \uc8fc\ud30c\uc218\ub85c \ubcc0\ud658\n                        const amplitude = dataArray&#x5B;i]; \/\/ \ud574\ub2f9 \uc8fc\ud30c\uc218 \uc601\uc5ed\uc758 \uc74c\ub7c9\n                        const calculVol = Math.round(amplitude * 100 \/ 255);\n\n                        frequencyData&#x5B;frequency] = calculVol; \/\/ \uac1d\uccb4\uc5d0 \ud0a4\uc640 \uac12\uc744 \uc800\uc7a5\n                  }\n\n                  console.log(&#039;\ubd84\uc11d \ub370\uc774\ud130&#039;, frequencyData);\n\n                  updateProgressBar();\n            }, 1000); \/\/ 1\ucd08\ub9c8\ub2e4 \ub370\uc774\ud130 \ub85c\uae45 \ubc0f \uc7ac\uc0dd\ubc14 \uc5c5\ub370\uc774\ud2b8\n\n            \/\/ HTML \uc694\uc18c\uc5d0 \uc624\ub514\uc624 \ucd94\uac00\n            document.body.appendChild(audio);\n      &lt;\/script&gt;\n&lt;\/body&gt;\n\n&lt;\/html&gt;\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>\uae30\ubcf8\uc801\uc778 \uc7ac\uc0dd\uae30 \uae30\ub2a5\uc5d0 \ucd94\uac00\uc801\uc73c\ub85c 1\ucd08\ub9c8\ub2e4 \uc8fc\ud30c\uc218 \ubd84\uc11d \uac12\uc744 \ucf58\uc194\uc5d0 \ucd9c\ub825\ud558\ub294 \ucf54\ub4dc\uc785\ub2c8\ub2e4. \uc0c1\ud669\uc5d0 \uc54c\ub9de\uac8c \uc218\uc815\ud574\uc11c \uc0ac\uc6a9\ud558\uba74 \ub418\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[95,7],"tags":[379,13,375,376,377,378],"class_list":["post-731","post","type-post","status-publish","format-standard","hentry","category-developed","category-javascript","tag-379","tag-13","tag-375","tag-376","tag-377","tag-mp3"],"modified_by":"\ucc38\ube5b\ubc14\ub2e4","_links":{"self":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/731","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=731"}],"version-history":[{"count":1,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/731\/revisions"}],"predecessor-version":[{"id":732,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=\/wp\/v2\/posts\/731\/revisions\/732"}],"wp:attachment":[{"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=731"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=731"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mydepot.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=731"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}