代码之家  ›  专栏  ›  技术社区  ›  metabolic

使用Web Audio Api播放的流中的单击声音

  •  5
  • metabolic  · 技术社区  · 11 年前

    我有一个奇怪的问题。我正在使用Web音频从服务器播放流。我的做法如下:

     var d2 = new DataView(evt.data);
    
    var data = new Float32Array(d2.byteLength / Float32Array.BYTES_PER_ELEMENT);
    for (var jj = 0; jj < data.length; ++jj) {
        data[jj] = d2.getFloat32(jj * Float32Array.BYTES_PER_ELEMENT, true);
    }
    
    var buffer = context.createBuffer(1, data.length, 44100);
    buffer.getChannelData(0).set(data);
    
    source = context.createBufferSource();
    source.buffer = buffer;
    source.start(startTime);
    source.connect(context.destination);
    
    startTime += buffer.duration;
    

    这很好。 如果我在电脑上播放流,我没有任何问题。

    如果我在我的Windows 8平板电脑(相同的Chrome版本)上播放相同的流,我的音频中会有很多点击声。一秒钟内有多个。 在每个缓冲区的末端我都能听到咔嗒声。

    我不明白区别。。。我唯一能发现的区别是,我电脑上声卡的采样率是44100,平板电脑上是48000。

    传输的流是44100,我没有任何采样率问题。只是咔嚓声。

    有人知道为什么会这样吗?

    非常感谢。 代谢的

    2 回复  |  直到 11 年前
        1
  •  2
  •   padenot    11 年前

    AudioBufferSourceNode将缓冲区重新采样到AudioContext采样率。可以想象,API不允许在一个AudioBufferSourceNode和另一个AudioBufferSourceNode之间保持重采样器状态,因此两个缓冲区之间存在不连续性。

    我认为最简单的方法是以设备的采样率提供流,通过服务器端重新采样。当AudioWorkerNode准备就绪并实现时,您将能够自己以及客户端修复此问题,但事实并非如此。

    或者,您也可以使用元素进行流式传输,并使用AudioContext.createMediaElementSource()将其传输到Web音频API。

        2
  •  1
  •   bain    6 年前

    我也有同样的问题,感谢帕德诺的回答,我检查了样本率。AudioContext.sampleRate默认为44100,但PCM数据和AudioBuffer为48000。使用匹配项初始化AudioContext sampleRate 解决了问题:

    var AudioContext = window.AudioContext || window.webkitAudioContext;
    var audioCtx = new AudioContext({
      latencyHint: 'interactive',
      sampleRate: 48000,
    });
    
    

    有了这个,我可以安排20ms 48khz PCM16 AudioBuffers背对背播放,无需任何点击或失真。