我正在尝试使用Chrome 51播放来自fetch API的无限流。(作为Microsoft PCM的网络摄像头音频流,16位,单声道11025 Hz)
代码对于mp3文件几乎没有问题,除了一些故障,但由于某种原因我无法使用wav文件,因为我得到“DOMException:无法解码音频数据”
代码改编自此答案Choppy/inaudible playback with chunked audio through Web Audio API
是否可以使其与WAV流一起使用?
function play(url) {
var context = new (window.AudioContext || window.webkitAudioContext)();
var audioStack = [];
var nextTime = 0;
fetch(url).then(function(response) {
var reader = response.body.getReader();
function read() {
return reader.read().then(({ value, done })=> {
context.decodeAudioData(value.buffer, function(buffer) {
audioStack.push(buffer);
if (audioStack.length) {
scheduleBuffers();
}
}, function(err) {
console.log("err(decodeAudioData): "+err);
});
if (done) {
console.log('done');
return;
}
read()
});
}
read();
})
function scheduleBuffers() {
while ( audioStack.length) {
var buffer = audioStack.shift();
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
if (nextTime == 0)
nextTime = context.currentTime + 0.01; /// add 50ms latency to work well across systems - tune this if you like
source.start(nextTime);
nextTime += source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played
};
}
}
只需使用play('/ path / to / mp3')来测试代码。 (服务器需要启用CORS,或者与运行脚本位于同一域中)
答案 0 :(得分:3)
AudioContext.decodeAudioData不是为解码部分文件而设计的;它适用于“短”(但完整)文件。由于MP3的分块设计,它有时适用于MP3流,但不适用于WAV文件。在这种情况下,您需要实现自己的解码器。
答案 1 :(得分:1)
正确地使wav流声音意味着像Raymond建议的那样将WAV标题添加到块中,加上一些webaudio魔术和paquet排序检查;
一些很酷的家伙帮我设置了那个模块来处理这个问题,它在Chrome上运行得非常漂亮:https://github.com/revolunet/webaudio-wav-stream-player
现在适用于Firefox 57+,其中包含一些配置标记:https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/getReader#Browser_compatibility