Javascript 可视化音频文件波形,Web音频API

Javascript 可视化音频文件波形,Web音频API,javascript,html5-canvas,signal-processing,web-audio-api,Javascript,Html5 Canvas,Signal Processing,Web Audio Api,我在尝试使用canvas可视化音频文件(.mp3,.wav)的波形时遇到了很多问题。实际上,在如何实现这一点上,我还很不清楚 我正在使用网络音频API。我一直在玩这里的代码来实现我的目标:。不幸的是,我遇到了问题。下面的例子 波形在画布上的外观: 歌曲的波形应该是什么样子。(这是艾伯顿的) 如果重要的话,这首歌的音频缓冲区大小是8832992 此歌曲的音频缓冲区(songAudioBuffer)如下所示: AudioBuffer { ​ duration: 184.020666666

我在尝试使用canvas可视化音频文件(.mp3,.wav)的波形时遇到了很多问题。实际上,在如何实现这一点上,我还很不清楚

我正在使用网络音频API。我一直在玩这里的代码来实现我的目标:。不幸的是,我遇到了问题。下面的例子

波形在画布上的外观:

歌曲的波形应该是什么样子。(这是艾伯顿的)

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

此歌曲的音频缓冲区(songAudioBuffer)如下所示:

AudioBuffer {

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

}
当前程序流程:用户从计算机中选择文件->用户单击加载->文件阅读器读取音频文件并将其转换为ArrayBuffer->获取ArrayBuffer并创建音频缓冲区

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();
}
const audioFile=document.querySelector('.audioFile')//用户加载音频文件的输入元素
const load=document.querySelector('.load')//按钮元素
load.addEventListener('单击',()=>{
const fileReader=new fileReader();
fileReader.readAsArrayBuffer(audioFile.files[0]);
fileReader.onload=函数(evt){
audioContext=新的audioContext();//全局变量
audioBuffer=audioContext.decodeAudioData(fileReader.result);//全局变量
//音频缓冲器类型
音频缓冲区。然后((res)=>{
songAudioBuffer=res;//songAudioBuffer是一个全局变量
画()
})
.catch((错误)=>{
控制台日志(err);
})
}
})
函数绘图(){
const canvas=document.querySelector('.can');//canvas元素
const canvasCtx=canvas.getContext('2d');
canvas.style.width=宽度+px;
canvas.style.height=高度+px;
canvasCtx.fillStyle='rgb(260200200)';
canvasCtx.fillRect(0,0,宽度,高度);
canvasCtx.lineWidth=2;
canvasCtx.strokeStyle='rgb(0,0,0)';
canvasCtx.beginPath();
const analyzer=audioContext.createanalyzer();
Analyzer.fftSize=2048;
const bufferLength=songAudioBuffer.getChannelData(0).length;
var dataArray=newfloat32array(songAudioBuffer.getChannelData(0));
Analyzer.getFloatTimeDomainData(songAudioBuffer.getChannelData(0));
var sliceWidth=宽度/缓冲区长度;
var x=0;
对于(变量i=0;i
只需后退几步,用-1和1之间的5个值填充一个数组,看看是否可以绘制该值。更容易看出哪里出了问题。

在哪里声明了
canvas
canvasCtx
?它们是全局变量。对不起,有点乱!我一直在玩弄代码,只是为了快速启动和运行什么是
songAudioBuffer
?@zer00ne更新了他们的代码,他们已经;“var v=dataArray[i]/128.0;”将您的值乘以2。有什么区别?