У меня много проблем с попыткой визуализировать форму звукового файла (.mp3, .wav) с помощью canvas.На самом деле, довольно невежественно о том, как этого добиться.
Я использую Web Audio API.Я играл с кодом здесь, чтобы достичь своей цели: https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API#Creating_a_waveformoscilloscope. К сожалению, у меня проблемы.Примеры ниже
Как форма волны выглядит с холстом:
Как должна выглядеть форма волны песни.(это из Ableton)
Если это имеет значение, размер аудиобуфера для этой песни, в частности, составляет 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();
}