2

我想捕获音频(在我的情况下来自getUserMedia)并播放。我可以像这样将一堆 AudioBuffers 推送到一个数组中:

var recorder = audio_context.createJavaScriptNode(256, 2, 2);
recorder.onaudioprocess = function(e) {
  recorded.push(e.inputBuffer.getChannelData(0));
  // or just:
  // recorded.push(e.inputBuffer);
};
recorder.connect(audio_context.destination);

但是那我如何播放recorded数组中的缓冲区呢?

一种将这些合并到一个缓冲区并与它一起播放的方法createBufferSource

完全不同的方法?

4

2 回答 2

2

录制完音频后,您应该能够执行以下操作:

var bufferIndex = 0;
recorder.onaudioprocess = function (e) {
  var outputData = e.outputbuffer.getChannelData(0);
  var recordedData = recorded[bufferIndex];
  for (var i = 0; i < recordedData.length; i++) {
    outputData[i] = recordedData[i];
  });
  bufferIndex++;
}

(您可能可以使其更简单/更清洁;这仅用于说明目的)

于 2012-10-31T08:38:57.353 回答
1

在我看来,最简单的方法是,正如您所建议的,将它们合并到一个 AudioBuffer 中并通过 AudioBufferSourceNode 播放。我将首先通过该context.createBuffer方法创建一个新的 AudioBuffer 对象,特别是使用 numberOfChannels、长度和 sampleRate 作为参数的版本。要计算长度(以秒为单位),您需要知道所有样本数组组合的大小......您可能希望在捕获它们时简单地保持运行总计(类似于recLength += currentBuffer.length)。然后,您可以通过将样本总数除以采样率来确定长度。采样率可以通过 确定context.sampleRate

使用适当的参数创建新的 AudioBuffer 对象后,您只需将保存的数组(您的recorded数组)复制到 AudioBuffer 的通道数据数组中。这是一个相当简单的两步过程:

  1. getChannelData(channel)通过 AudioBuffer 的方法检索底层通道数据
  2. 遍历您的recorded数组并通过该.set(array, offset)方法将保存的数据复制到通道数据数组中(有关更多信息,请参阅MDN Float32Array 文档)。channelData.set(currArray, currOffset)随着currOffset每个存储数组的长度增加,您的代码看起来会像这样。

注意:如果您正在录制两个音频通道,您将拥有两个记录样本数组,您必须为每个通道(0 和 1)执行上述两个步骤,复制相应的数组。

如果操作正确,您将拥有一个 AudioBuffer,您可以将其插入 AudioBufferSourceNode 并按您认为合适的方式播放。

于 2012-10-31T18:29:02.683 回答