如何编写JavaScript程序以显示音频文件中的波形?我想使用Web Audio和Canvas。
我试过这段代码:
(new window.AudioContext).decodeAudioData(audioFile, function (data) {
var channel = data.getChannelData(0);
for (var i = 0; i < channel; i++) {
canvas.getContext('2d').fillRect(i, 1, 40 - channel[i], 40);
}
});
但是结果远非我想要的(即,由于我用矩形绘制,图像不平滑)。我希望它看起来像这张图像一样平滑:
有关如何实现波形的任何提示?
答案 0 :(得分:41)
答案 1 :(得分:9)
您可能对AudioJedit感兴趣。这是一个开源项目hosted at GitHub。它有用于加载音频文件的小型服务器端node.js脚本,但是在客户端JavaScript中实现了与音频的所有交互。我认为这与您所寻找的类似。
答案 2 :(得分:2)
对于(希望)简单使用和集成波形与您的应用程序,您可能想要检查我们在IRCAM上做了什么,特别是在这种特殊情况下的波形可见。
它是所有开源的,旨在模块化(并且正在进行中)
您可以找到demo over here
以及相应的githug repository
答案 3 :(得分:0)
您的渲染代码效率极低,因为它会为每秒音频渲染44100像素。您希望最好使用缩小的数据集渲染视口宽度。
可以使用audioDurationSeconds * samplerate / viewPortWidthPx计算在视口中拟合波形所需的每像素采样范围。因此,对于1000px的视口和44100采样率的2秒的音频文件,每像素的样本=(2 * 44100)/ 1000 = ~88。 对于屏幕上的每个像素,您可以从该样本范围中获取最小值和最大值,然后使用此数据绘制波形。
这是一个执行此操作的示例算法,但允许您将每个像素的样本作为参数以及滚动位置,以允许虚拟滚动和缩放。它包含一个可以调整性能的分辨率参数,这表示每个像素样本范围应采用的样本数量: this thread
那里的绘制方法与你的类似,为了平滑它你需要使用lineTo而不是fillRect。这个差异实际上不应该那么大,我想你可能忘记设置宽度和高度画布上的属性。在css中设置此选项会导致绘图模糊,您需要设置属性。
let drawWaveform = function(canvas, drawData, width, height) {
let ctx = canvas.getContext('2d');
let drawHeight = height / 2;
// clear canvas incase there is already something drawn
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.moveTo(0, drawHeight);
for(let i = 0; i < width; i++) {
// transform data points to pixel height and move to centre
let minPixel = drawData[i][0] * drawHeigth + drawHeight;
ctx.lineTo(i, minPixel);
}
ctx.lineTo(width, drawHeight);
ctx.moveTo(0, drawHeight);
for(let i = 0; i < width; i++) {
// transform data points to pixel height and move to centre
let maxPixel = drawData[i][1] * drawHeigth + drawHeight;
ctx.lineTo(i, maxPixel);
}
ctx.lineTo(width, drawHeight);
ctx.closePath();
ctx.fill(); // can do ctx.stroke() for an outline of the waveform
}