javascript - 可视化音频文件波形,Web Audio API

标签 javascript html5-canvas signal-processing web-audio-api

我在尝试使用 Canvas 可视化音频文件(.mp3、.wav)的波形时遇到了很多麻烦。实际上,对于如何实现这一目标一无所知。

我正在使用网络音频 API。我一直在玩弄这里的代码以实现我的目标:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API#Creating_a_waveformoscilloscope .不幸的是,我遇到了问题。下面的例子

波形在 Canvas 上的样子:

Image of waveform

歌曲波形的外观。 (这是来自 Ableton) enter image description here

如果重要的话,这首歌的音频缓冲区大小特别是 8832992。

这首歌的音频缓冲区(songAudioBuffer)是这样的:

AudioBuffer {

​    duration: 184.02066666666667,
​    length: 8832992,
​    numberOfChannels: 2,
    sampleRate: 48000

}

当前程序流程:用户从他们的计算机中选择一个文件 -> 用户点击加载 -> FileReader 读取音频文件并将其转换为 ArrayBuffer -> 获取 ArrayBuffer 并创建一个 AudioBuffer

const audioFile = document.querySelector('.audioFile') // Input element where user loads the audio file to
const load = document.querySelector('.load') // button element
load.addEventListener('click', () => {

    const fileReader = new FileReader();


    fileReader.readAsArrayBuffer(audioFile.files[0]);
    fileReader.onload = function(evt){

        audioContext = new AudioContext(); // global var

        audioBuffer = audioContext.decodeAudioData(fileReader.result); // global var

        // Type of AudioBuffer
        audioBuffer.then((res) => {

            songAudioBuffer = res; // songAudioBuffer is a global var
            draw()

        })
        .catch((err) => {
            console.log(err);
        })
    }
})


function draw(){

    const canvas = document.querySelector('.can'); // canvas element
    const canvasCtx = canvas.getContext('2d');



    canvas.style.width = WIDTH + 'px';
    canvas.style.height = HEIGHT + 'px';

    canvasCtx.fillStyle = 'rgb(260, 200, 200)';
    canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

    canvasCtx.lineWidth = 2;
    canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
    canvasCtx.beginPath();


    const analyser = audioContext.createAnalyser();
    analyser.fftSize = 2048;

    const bufferLength = songAudioBuffer.getChannelData(0).length;
    var dataArray = new Float32Array(songAudioBuffer.getChannelData(0));
    analyser.getFloatTimeDomainData(songAudioBuffer.getChannelData(0));


    var sliceWidth = WIDTH / bufferLength;
    var x = 0;


    for(var i = 0; i < bufferLength; i++) {

        var v = dataArray[i] * 2;
        var y = v + (HEIGHT / 4); // Dividing height by 4 places the waveform in the center of the canvas for some reason

        if(i === 0) canvasCtx.moveTo(x, y);
        else {
            canvasCtx.lineTo(x, y);
        }

        x += sliceWidth;
    }


    canvasCtx.lineTo(canvas.width, canvas.height / 2);
    canvasCtx.stroke();
}

最佳答案

只需退后几步,用 -1 到 1 之间的 5 个值填充一个数组,看看你是否可以绘制它。更容易看出问题所在。

关于javascript - 可视化音频文件波形,Web Audio API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54582125/

相关文章:

javascript - 让 Kinetic 使用我现有的 Canvas

speech-recognition - "Voice trigger"检测

javascript - 可选参数和默认值

javascript - 在 IE 中的表中追加 tr

javascript - 在 Javascript 中,如果属性不存在,如何自动将其设置为 null?

javascript - 显示 OpenLayers map 时 JavaFX WebView 不准确

javascript - Canvas 2d 上下文的measureText() 方法有时会给出不同的宽度

javascript - HTML5 Canvas - 在更新循环中绘制图像

android - Android 上的 MP3 解码速度慢

algorithm - 自相关算法在高频下失败