آموزش HTML - پخش‌کننده صوتی

در این بخش، نحوه ساخت یک پخش‌کننده صوتی اختصاصی به همراه اکولایزر (تجسم‌ساز بصری) در HTML را یاد خواهیم گرفت.

قابلیت‌های HTML شامل پشتیبانی بومی از صوت و ویدیو بدون نیاز به Flash است. کد زیر بر پایه HTML، CSS و JavaScript کار می‌کند. شما می‌توانید فایل‌های MP3 محلی خود را بکشید و درون کانتینر رها کنید (Drag and Drop).

توصیه می‌کنیم برای یادگیری بیشتر درباره جاسازی صوت در HTML و تگ <audio> این فصل‌ها را مطالعه کنید.

فایل‌های کد برای ساخت پخش‌کننده صوتی HTML

بیاین به مثال زیر نگاه کنیم، جایی که قصد داریم یک اکولایزر صوتی محلی بسازیم

۱. فایل HTML

<!DOCTYPE html>
<html>
   <style>
      #instructions {
         width: 100%;
         text-align: center;
         top: 50%;
         margin-top: -100px;
         color: #DE3163;
      }

      #container {
         position: absolute;
         width: 100%;
         height: 100%;
         background: #D5F5E3;
      }

      #canvas-container {
         width: 600px;
         height: 600px;
         margin: auto;
         position: relative;
         top: 50%;
         margin-top: -263px;
         margin-right: -61px;
      }

      #canvas-copy {
         opacity: 0.05;
         -webkit-transform: scaleY(-1);
         margin-top: -6px;
      }
   </style>
<body>
   <div id="container">
      <div id="canvas-container">
         <canvas width=600 height=300 id="canvas"></canvas>
         <canvas width=600 height=300 id="canvas-copy"></canvas>
      </div>
      <div id="instructions">
         <a href="https://www.tutorialspoint.com/index.htm" align="center"> Tutorials Point</a>
         <h2 style="font-family:verdana"> Drag Your Local MP3 Files </h2>
      </div>
      <div id="button"></div>
   </div>
   <script src="js.html"></script>
</body>
</html>

اکنون یک فایل جاوااسکریپت با نام ذکرشده در فایل HTML بالا می‌سازیم.

۲. فایل JavaScript

<script>
   (function() {
      var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
      window.requestAnimationFrame = requestAnimationFrame;
   })();
   window.onload = function() {
      var element = document.getElementById('container')
      dropAndLoad(element, init, "ArrayBuffer")
   }

   function dropAndLoad(dropElement, callback, readFormat) {
      var readFormat = readFormat || "DataUrl"
      dropElement.addEventListener('dragover', function(e) {
         e.stopPropagation()
         e.preventDefault()
         e.dataTransfer.dropEffect = 'copy'
      }, false)
      dropElement.addEventListener('drop', function(e) {
         e.stopPropagation()
         e.preventDefault()
         loadFile(e.dataTransfer.files[0])
      }, false)

      function loadFile(files) {
         var file = files
         var reader = new FileReader()
         reader.onload = function(e) {
            callback(e.target.result)
         }
         reader['readAs' + readFormat](file)
      }
   }

   function init(arrayBuffer) {
      document.getElementById('instructions').innerHTML = 'Audio Loading'
      window.audioCtx = new AudioContext()
      window.analyser = audioCtx.createAnalyser()
      if (window.source) source.noteOff(0)
      audioCtx.decodeAudioData(arrayBuffer, function(buffer) {
         window.source = audioCtx.createBufferSource()
         source.buffer = buffer
         source.connect(analyser)
         analyser.connect(audioCtx.destination)
         source.start(0)
         var viz = new simpleViz()
         new visualizer(viz['update'], analyser)
         document.getElementById('instructions').innerHTML = ''
      })
   }

   function visualizer(visualization, analyser) {
      var self = this
      this.visualization = visualization
      var last = Date.now()
      var loop = function() {
         var dt = Date.now() - last
         var byteFreq = new Uint8Array(analyser.frequencyBinCount)
         analyser.getByteFrequencyData(byteFreq)
         last = Date.now()
         self.visualization(byteFreq, dt)
         requestAnimationFrame(loop)
      }
      requestAnimationFrame(loop)
   }

   function simpleViz(canvas) {
      var self = this
      this.canvas = document.getElementById('canvas')
      this.ctx = this.canvas.getContext("2d")
      this.copyCtx = document.getElementById('canvas-copy').getContext("2d")
      this.ctx.fillStyle = '#fff'
      this.barWidth = 10
      this.barGap = 4
      this.bars = Math.floor(this.canvas.width / (this.barWidth + this.barGap))
      this.update = function(byteFreq) {
         self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height)
         var step = Math.floor(byteFreq.length / self.bars)
         for (var i = 0; i < self.bars; i++) {
            var barHeight = byteFreq[i * step]
            self.ctx.fillRect(i * (self.barWidth + self.barGap), self.canvas.height - barHeight, self.barWidth, barHeight)
            self.copyCtx.clearRect(0, 0, self.canvas.width, self.canvas.height)
            self.copyCtx.drawImage(self.canvas, 0, 0)
         }
      }
   }
</script>

کد کامل برای ساخت پخش‌کننده صوتی HTML

بیاین هر دو فایل را ترکیب کنیم و خروجی حاصل را مشاهده کنیم.

<!DOCTYPE html>
<html>
   <style>
      #instructions {
         width: 100%;
         text-align: center;
         top: 50%;
         margin-top: -100px;
         color: #DE3163;
      }

      #container {
         position: absolute;
         width: 100%;
         height: 100%;
         background: #D5F5E3;
      }

      #canvas-container {
         width: 600px;
         height: 600px;
         margin: auto;
         position: relative;
         top: 50%;
         margin-top: -263px;
         margin-right: -61px;
      }

      #canvas-copy {
         opacity: 0.05;
         -webkit-transform: scaleY(-1);
         margin-top: -6px;
      }
   </style>
<body>
   <div id="container">
      <div id="canvas-container">
         <canvas width=600 height=300 id="canvas"></canvas>
         <canvas width=600 height=300 id="canvas-copy"></canvas>
      </div>
      <div id="instructions">
         <a href="https://www.tutorialspoint.com/index.htm" align="center"> Tutorials Point</a>
         <h2 style="font-family:verdana"> Drag Your Local MP3 Files </h2>
      </div>
      <div id="button"></div>
   </div>
   <script>
      (function() {
         var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
         window.requestAnimationFrame = requestAnimationFrame;
      })();
      window.onload = function() {
         var element = document.getElementById('container')
         dropAndLoad(element, init, "ArrayBuffer")
      }

      function dropAndLoad(dropElement, callback, readFormat) {
         var readFormat = readFormat || "DataUrl"
         dropElement.addEventListener('dragover', function(e) {
            e.stopPropagation()
            e.preventDefault()
            e.dataTransfer.dropEffect = 'copy'
         }, false)
         dropElement.addEventListener('drop', function(e) {
            e.stopPropagation()
            e.preventDefault()
            loadFile(e.dataTransfer.files[0])
         }, false)

         function loadFile(files) {
            var file = files
            var reader = new FileReader()
            reader.onload = function(e) {
               callback(e.target.result)
            }
            reader['readAs' + readFormat](file)
         }
      }

      function init(arrayBuffer) {
         document.getElementById('instructions').innerHTML = 'Audio Loading'
         window.audioCtx = new AudioContext()
         window.analyser = audioCtx.createAnalyser()
         if (window.source) source.noteOff(0)
         audioCtx.decodeAudioData(arrayBuffer, function(buffer) {
            window.source = audioCtx.createBufferSource()
            source.buffer = buffer
            source.connect(analyser)
            analyser.connect(audioCtx.destination)
            source.start(0)
            var viz = new simpleViz()
            new visualizer(viz['update'], analyser)
            document.getElementById('instructions').innerHTML = ''
         })
      }

      function visualizer(visualization, analyser) {
         var self = this
         this.visualization = visualization
         var last = Date.now()
         var loop = function() {
            var dt = Date.now() - last
            var byteFreq = new Uint8Array(analyser.frequencyBinCount)
            analyser.getByteFrequencyData(byteFreq)
            last = Date.now()
            self.visualization(byteFreq, dt)
            requestAnimationFrame(loop)
         }
         requestAnimationFrame(loop)
      }

      function simpleViz(canvas) {
         var self = this
         this.canvas = document.getElementById('canvas')
         this.ctx = this.canvas.getContext("2d")
         this.copyCtx = document.getElementById('canvas-copy').getContext("2d")
         this.ctx.fillStyle = '#fff'
         this.barWidth = 10
         this.barGap = 4
         this.bars = Math.floor(this.canvas.width / (this.barWidth + this.barGap))
         this.update = function(byteFreq) {
            self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height)
            var step = Math.floor(byteFreq.length / self.bars)
            for (var i = 0; i < self.bars; i++) {
               var barHeight = byteFreq[i * step]
               self.ctx.fillRect(i * (self.barWidth + self.barGap), self.canvas.height - barHeight, self.barWidth, barHeight)
               self.copyCtx.clearRect(0, 0, self.canvas.width, self.canvas.height)
               self.copyCtx.drawImage(self.canvas, 0, 0)
            }
         }
      }
   </script>
</body>
</html>

هنگامی که کد بالا را اجرا می‌کنیم، خروجی تولید می‌شود که شامل متنی همراه با استایل CSS است که راهنمایی می‌کند فایل MP3 محلی را برای پخش موسیقی بکشید و رها کنید.

پخش‌کننده صوتی HTML همراه با لیست پخش (Playlist)

مثال زیر را در نظر بگیرید، جایی که به کاربر اجازه می‌دهیم چند فایل MP3 محلی را بارگذاری کند تا به عنوان یک لیست پخش عمل کنند.

<!DOCTYPE html>
<html>
<body style="background-color:#ABEBC6;">
   <audio controls id="y" autoplay></audio>
   <br>
   <br>
   <br>
   <input type="file" id="x" multiple>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
   <script>
      var x = document.getElementById("x"),
         y = document.getElementById("y");

      function next(n) {
         var a = URL.createObjectURL(z[n]);
         y.setAttribute('src', a);
         y.play();
      }
      var _next = 0,
         z,
         len;
      x.addEventListener('Change', function() {
         z = x.z;
         len = z.length;
         if (len) {
            next(_next);
         }
      });
      y.addEventListener("Completed", function() {
         _next += 1;
         next(_next);
         console.log(len, _next);
         if ((len - 1) == _next) {
            _next = -1;
         }
      });
   </script>
</body>
</html>

با اجرای کد بالا، پنجره خروجی ظاهر می‌شود و به کاربر اجازه می‌دهد چندین فایل mp3 را بارگذاری کند و آن‌ها را به‌طور خودکار در صفحه وب پخش نماید.

پیشرفت مطالعه: وضعیت خوانده‌شدن این درس فقط در همین مرورگر ذخیره می‌شود؛ بدون نیاز به حساب کاربری.