我有一个网页,由于某些原因解码波形文件。 Chrome和Safari似乎运行良好。 Firefox偶尔无法解码文件并提供错误:"传递给decodeAudioData的缓冲区包含无法成功解码的无效内容。"我创建了一个jsfiddle来说明问题:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source;
function getData() {
source = audioCtx.createBufferSource();
request = new XMLHttpRequest();
request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true);
request.responseType = 'arraybuffer';
request.onload = function() {
var audioData = request.response;
audioCtx.decodeAudioData(audioData, function(buffer) {
source.buffer = buffer;
source.connect(audioCtx.destination);
},
function(e){"Error with decoding audio data" + e.err});
}
request.send();
}
getData();
source.start(0);
谁能告诉我这是什么问题,是否有办法绕过?非常感谢。
修改 感谢Michael Chaney的大量贡献,我能够实现一些处理wave的javascript,以便它可以在Firefox中播放。代码修剪了" fmt"的任何部分。超过16个字节的块。代码位于:jfiddle
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source;
function getData() {
source = audioCtx.createBufferSource();
request = new XMLHttpRequest();
request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true);
request.responseType = 'arraybuffer';
request.onload = function() {
var audioData = request.response;
var dv = new DataView(audioData);
var junk = 0;
var position = 12;
do {
var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4));
var length = dv.getUint32(position + 4, true);
if (header.trim() === 'fmt') {
junk = junk + length - 16;
}
position = position + 8 + length;
}while(position < audioData.byteLength);
var productArray = new Uint8Array(audioData.byteLength - junk);
productArray.set(new Uint8Array(audioData, 0, 12));
var newPosition = 12;
position = 12;
var fmt_length_spot;
do {
var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4));
var length = dv.getUint32(position + 4, true);
if (header.trim() === 'fmt') {
productArray.set(new Uint8Array(audioData, position, 24), newPosition);
fmt_length_spot = newPosition + 4;
newPosition = newPosition + 24;
}
else {
productArray.set(new Uint8Array(audioData, position, length + 8), newPosition);
newPosition = newPosition + 8 + length;
}
position = position + 8 + length;
}while(position < audioData.byteLength);
audioData = productArray.buffer;
dv = new DataView(audioData);
dv.setUint32(4, audioData.byteLength - 8, true);
dv.setUint32(fmt_length_spot, 16, true);
audioCtx.decodeAudioData(audioData, function(buffer) {
source.buffer = buffer;
source.connect(audioCtx.destination);
},
function(e){"Error with decoding audio data" + e.err});
}
request.send();
}
getData();
source.start(0);
谢谢Michael。
答案 0 :(得分:3)
它可能是文件开头的JUNK块。您可以通过sox运行它来清除这样的无关块:
sox Malice_Bass.wav Malice_Bass_simple.wav
以下是我的个人解析器对该文件的说法:
RIFF - WAVE (36467192 bytes)
JUNK (92)
bext (602)
Description:
Originator: Pro Tools
Originator Ref: jicj!dad1ofaaaGk
Origination Date: 2014-09-09
Origination Time: 20:46:43
Time Ref Low: 0
Time Ref High: 0
BWF Version: 0
SMPTE UMID Bytes: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Coding History:
fmt (40)
Format Tag: 1
Channels: 2
Samples per sec: 48000
Avg bytes per sec: 192000
Block align: 4
Bits per sample: 16
minf (16)
elm1 (214)
data (36466048)
regn (92)
umid (24)
当我使用sox Firefox清理它时,会退出抱怨,但仍然无法播放它。我确认它加载了文件,但似乎没有播放它。
答案 1 :(得分:2)
我最近遇到这个问题,Firefox没有使用浏览器的音频api读取wav文件,发现问题是音频文件的位深度不应超过16位才能被Firefox识别。我也发现这是一个8岁的Firefox“bug”,这是非常令人惊讶的(https://bugzilla.mozilla.org/show_bug.cgi?id=524109)
我的灵魂是通过这样的sox命令行将32位深度的任何wav文件降级到16位:sox input.wav -b 16 output.wav。您显然可以使用ffmpeg或任何其他可以在Linux下执行此操作的应用程序。 希望有所帮助。
答案 2 :(得分:1)
该wav文件在前20秒内保持静音。我刚刚下载了它:
wget https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav
我尝试使用镀铬而小提琴是沉默的,最初我想 因为我只是使用笔记本电脑扬声器。 使用大胆的FFT表示它在20秒静音后开始的频率非常低。
Web Audio API使用计算机的默认采样率,即 通常为44.1kHz由于文件使用的是48 kHz,因此是您的机器 配置48 kHz的宽松率?如果你重新采样48 kHz到44.1kHz的文件,这是典型计算机的采样率,它可能会有效。