如何使用HTML CANVAS API创建音频可视化器

如何使用HTML CANVAS API创建音频可视化器

在本文中,我们将看到如何使用canvas API创建音频可视化器。 Canvas API用于在HTML画布元素上绘制图形。因此,借助这个功能,我们将创建一个根据系统麦克风的音频响应的音频可视化器。

音频可视化器 可以定义为一种通过动画图像直观显示音乐的节奏、音量和频率的工具。

使用的类:

  • MediaDevices: 用于访问媒体。
  • AudioContext: 用于创建分析器。

使用的方法:

  • getUserMedia: 用于访问麦克风。
  • createMediaStreamSource: 使用流创建一个源,以创建音频可视化器。
  • getContext: 该方法用于访问画布上下文。
  • requestAnimationFrame: 该方法用于创建动画。

方法:

  • 创建一个用于绘制可视化器的画布元素,以及一个用于在HTML代码中访问系统音频的按钮。
  • 使用 navigator API 访问麦克风,该API返回一个流对象。 MediaDevices 是提供访问音频流的类,仅能通过用户事件进行访问,因此创建一个按钮并注册一个函数,如下所示。

语法:

var btn = document.getElementById("mybtn");
btn.onclick = async()=>{
 let stream =await navigator.mediaDevices.getUserMedia({
     audio: true,
     video: true
   });
}

在上面的代码中,我们有一个按钮,其中包含一个回调函数,用于单击事件访问音频设备。

创建一个 AudioContext 类的实例,并将流对象传递给它,如下所示。同时,创建一个分析器,用于通过创建数据可视化来分析音频节点。

语法:

 const audioContext = new AudioContext();
 const analyser = audioContext.createAnalyser();
 const mediaStreamSource = 
     audioContext.createMediaStreamSource(stream);
 mediaStreamSource.connect(analyser);
analyser.fftSize = 256;

定义一个函数 drawVisualizer() ,使用 requestAnimationFrame 函数以特定的帧率连续调用自身,以反映音频信号的变化。

将g>drawVisualizer**函数中的canvas API方法添加进去,以创建最终的可视化效果,如下所示:

function drawVisualizer() {
  requestAnimationFrame(drawVisualizer);

  const bufferLength = analyser.frequencyBinCount;
  const dataArray = new Uint8Array(bufferLength);
  analyser.getByteFrequencyData(dataArray);

  const width = visualizer.width;
  const height = visualizer.height;
  const barWidth = 10;

  const canvasContext = visualizer.getContext('2d');
  canvasContext.clearRect(0, 0, width, height);
  let x = 0;
  dataArray.forEach((item, index,array) => {
   const y = item / 255 * height*1.1;
   canvasContext.strokeStyle = `blue`;
   x = x + barWidth;
   canvasContext.beginPath();
   canvasContext.lineCap = "round";
   canvasContext.lineWidth = 2;
   canvasContext.moveTo(x, height);
   canvasContext.lineTo(x, height - y);
   canvasContext.stroke();
  })
}

在上面的代码片段中,首先,我们声明一个类型化数组,以整数值的形式存储音频节点 例如 dataArray 然后,我们通过JS选择器访问上面创建的canvas元素 例如 visualizer 并访问canvas的2D上下文 例如 canvasContext 我们循环遍历 dataArray 的元素,并为每个元素绘制一条从canvas元素底部到点 (x,height – y) 的线路径。在上面的代码中,我们为线条赋予了蓝色,并将线宽设置为2,这样我们可以绘制多条垂直线。

示例: 在这个示例中,我们使用canvas API、AudioContext和mediaDevices创建了一个音频可视化器。

HTML

<!DOCTYPE html>
<html>
 
<head>
    <title>
        Creating an audio visualizer
        using HTML CANVAS API
    </title>
</head>
 
<body>
    <h1 style="color:green">
        GeeksforGeeks
    </h1>
    <h3>
        How to make an audio visualizer
        with HTML CANVAS API?
    </h3>
 
    <button id="mybtn">Click Me</button>
     
    <canvas id="visualizer" width="100px"
        height="100px" style="border:5px solid blue;
                   border-radius:100px">
    </canvas>
 
    <script type="text/javascript">
        var btn = document.getElementById("mybtn");
        var visualizer = document.getElementById("visualizer");
        btn.onclick = async () => {
            let stream = await navigator.mediaDevices.getUserMedia({
                audio: true,
                video: true
            });
 
            const audioContext = new AudioContext();
            const analyser = audioContext.createAnalyser();
            const mediaStreamSource =
                audioContext.createMediaStreamSource(stream);
 
            // Connecting the analyzer to the media source
            mediaStreamSource.connect(analyser);
            analyser.fftSize = 256;
            drawVisualizer();
 
            function drawVisualizer() {
                requestAnimationFrame(drawVisualizer)
                const bufferLength = analyser.frequencyBinCount
                const dataArray = new Uint8Array(bufferLength)
 
                // Updating the analyzer with the new 
                // generated data visualization
                analyser.getByteFrequencyData(dataArray)
                const width = visualizer.width
                const height = visualizer.height
                const barWidth = 10
                const canvasContext = visualizer.getContext('2d')
                canvasContext.clearRect(0, 0, width, height)
                let x = 0
                dataArray.forEach((item, index, array) => {
 
                    // This formula decides the height of the vertical
                    // lines for every item in dataArray
                    const y = item / 255 * height * 1.1
                    canvasContext.strokeStyle = `blue`
                     
                    // This decides the distances between the
                    // vertical lines
                    x = x + barWidth
                    canvasContext.beginPath();
                    canvasContext.lineCap = "round";
                    canvasContext.lineWidth = 2;
                    canvasContext.moveTo(x, height);
                    canvasContext.lineTo(x, height - y);
                    canvasContext.stroke();
                })
            }
        }
    </script>
</body>
 
</html>

输出: 此输出由一个蓝色的圆形可视化器和旁边的一个按钮组成,用于访问系统的媒体资源。

如何使用HTML CANVAS API创建音频可视化器

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程