问题描述
我有一个网页,由于某些原因解码波形文件。 Chrome和Safari似乎工作正常。 Firefox偶尔无法解码文件,并给出错误:传递给decodeAudioData的缓冲区包含无法成功解码的无效内容。我已经创建了一个,说明了这个问题:
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var source;
函数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){音频数据解码出错+ e.err});
}
request.send();
}
getData();
source.start(0);
任何人都可以告诉我问题是什么,是否有办法避开?很多谢谢。
$ b $ p 编辑
由于Michael Chaney能够实现的巨大贡献,一些JavaScript处理波,以便它可以在Firefox中播放。代码修剪16字节的fmt块的任何部分。代码位于:
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var source;
函数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){音频数据解码出错+ e.err});
}
request.send();
}
getData();
source.start(0);
谢谢Michael。
它可能是文件开头的JUNK块。你可以通过sox来运行它,以清除不必要的块:
sox Malice_Bass.wav Malice_Bass_simple.wav
以下是我的个人解析器对文件所说的内容:
<$ p $
原始码:Pro Tools
原始码(R) - 波形(36467192字节)
JUNK(92)
bext(602)
Ref:jicj!dad1ofaaaGk
起源日期:2014-09-09
起始时间:20:46:43
时间参考最低价:0
时间参考最高价:
BWF版本:0
SMPTE UMID字节数: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
编码历史:
fmt(40)
格式标签:1
频道:2
每秒采样数:48000
每秒平均字节数:192000
块对齐:4
每个样本的位数:16
minf(16)
elm1(214)
data(36466048)
regn(92)
umid(24)
当我使用sox进行清理时,Firefox停止抱怨,但仍然没有不玩。我确认它加载的文件,但似乎并没有玩。
I have a web page which decodes wave files for certain reasons. Chrome and Safari seem to work fine. Firefox occasionally is unable to decode the file and gives the error: "The buffer passed to decodeAudioData contains invalid content which cannot be decoded successfully." I have created a jsfiddle which illustrates the issue:
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);
Can anyone tell me what the issue is and if there is any way to circumvent? Many Thanks.
EDITThanks to the substantial contributions of Michael Chaney I was able to implement some javascript which processes the wave so that it can be played in Firefox. The code trims any part of the "fmt" chunk over 16 bytes. Code located at: 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);
Thanks Michael.
It might be the JUNK chunk at the start of the file. You can run it through sox to clean out extraneous chunks like this:
sox Malice_Bass.wav Malice_Bass_simple.wav
Here's what my personal parser says about the file:
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)
When I clean it up using sox Firefox quits complaining about it but still doesn't play it. I confirmed that it loads the file but doesn't seem to play it.
这篇关于为什么某些.wav文件无法在Firefox中解码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!