Web音频API不能连续播放声音

时间:2017-06-04 23:33:06

标签: javascript node.js socket.io buffer web-audio-api

我正在尝试使用节点js和socket io实时缓冲MP3歌曲。我基本上将MP3分成几段字节并将其发送到客户端,网络音频API将接收它,解码并开始播放。这里的问题是声音不能连续播放,每个缓冲段之间有0.5秒的差距。我该如何解决这个问题

// buffer is a 2 seconds decoded audio ready to be played 
// the function is called  when a new buffer is recieved
function stream(buffer)
{
    // creates a new buffer source and connects it to the Audio context
    var source = context.createBufferSource();
    source.buffer = buffer;
    source.connect(context.destination);
    source.loop = false;
    // sets it and updates the time 
    source.start(time + context.currentTime);

    time += buffer.duration; // time is global variable initially set to zero
}

称为流的部分

    // where stream bufferQ is an array of decoded MP3 data 
    // so the stream function is called after every 3 segments that are recieved 
     // the Web audio Api plays it with gaps between the sound
    if(bufferQ.length == 3)
    {
        for(var i = 0, n = bufferQ.length ; i < n; i++)
        {
              stream(bufferQ.splice(0,1)[0]);
        }
    }

我应该使用除了网络音频API之外的其他API,还是有办法安排我的缓冲区以便连续播放?

2 个答案:

答案 0 :(得分:0)

这是mp3文件的问题,每个mp3文件在开始和结束时都有几帧静音。 如果你使用wav文件或正确计时每个文件的开始和停止,你可以修复它

答案 1 :(得分:0)

context.currentTime将根据评估时间的不同而有所不同,并且由于四舍五入到最接近的2ms左右,因此每次读取都有隐式的误差(请参见Firefox BaseAudioContext/currentTime#Reduced time precision)。考虑:

function stream(buffer)
{
...
source.start(time + context.currentTime);

time += buffer.duration; // time is global variable initially set to zero

为每个PCM数据块调用source.start(time + context.currentTime)总是将在当前时间(四舍五入到2ms)加上{{1} }偏移量。

要播放背对背PCM块,请在流的开头读取一次currentTime,然后在安排播放后将每个持续时间添加到该时间。例如,PCMPlayer执行以下操作:

time

注意PCMPlayer.prototype.flush = function() { ... if (this.startTime < this.audioCtx.currentTime) { this.startTime = this.audioCtx.currentTime; } ... bufferSource.start(this.startTime); this.startTime += audioBuffer.duration; }; 仅在它代表过去的时间时才被重置-对于连续缓冲的流,它不会被重置,因为它将在将来的某个时间值。在每次刷新调用中,startTime用于安排回放,并且仅随着每个PCM数据持续时间而增加,而与currentTime无关。


另一个潜在的问题是,您正在解码的PCM缓冲区的采样率可能与AudioContext的采样率不匹配。在这种情况下,浏览器将分别对每个PCM缓冲区重新采样,从而导致块边界不连续。参见Clicking sounds in Stream played with Web Audio Api