lae*_*des 5 javascript firefox wav html5-audio web-audio-api
我有一个网页,由于某些原因解码波形文件.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);
Run Code Online (Sandbox Code Playgroud)
谁能告诉我这是什么问题,是否有办法绕过?非常感谢.
编辑 感谢Michael Chaney的大量贡献,我能够实现一些处理wave的javascript,以便它可以在Firefox中播放.代码修剪了16个字节的"fmt"块的任何部分.代码位于: 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);
Run Code Online (Sandbox Code Playgroud)
谢谢迈克尔.
小智 5
我最近遇到了 Firefox 没有使用浏览器的音频 api 读取 wav 文件的问题,并发现问题在于音频文件的位深度不应超过 16 位,以便 Firefox 识别。我还发现这是一个 8 岁的 Firefox “错误”,这非常令人惊讶(https://bugzilla.mozilla.org/show_bug.cgi?id=524109)
我的灵魂是通过 sox 命令行将任何 32 位深度的 wav 文件降级到 16 位,如下所示:sox input.wav -b 16 output.wav。您显然可以使用 ffmpeg 或任何其他可以在 Linux 下执行此操作的应用程序。希望有帮助。
它可能是文件开头的垃圾块。您可以通过 sox 运行它来清除无关的块,如下所示:
sox Malice_Bass.wav Malice_Bass_simple.wav
Run Code Online (Sandbox Code Playgroud)
这是我的个人解析器对该文件的描述:
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)
Run Code Online (Sandbox Code Playgroud)
当我使用 sox 清理它时,Firefox 不再抱怨它,但仍然不播放它。我确认它加载了文件但似乎没有播放它。