我想捕获音频(在我的情况下来自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
进行播放的方法吗?
完全不同的做法?
答案 0 :(得分: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++;
}
(你可能会更简单/更清洁;这只是为了说明目的)
答案 1 :(得分:1)
在我看来,最简单的方法是,正如你的建议,将它们合并到一个AudioBuffer中并通过AudioBufferSourceNode播放它。我将首先通过context.createBuffer
方法创建一个新的AudioBuffer对象,特别是将numberOfChannels,length和sampleRate作为参数的版本。要计算长度(以秒为单位),您需要知道所有样本数组的大小......您可能希望在捕获它们时简单地保持其总计(类似recLength += currentBuffer.length
)。然后,您可以通过将样本总数除以采样率来确定长度。可以通过context.sampleRate
确定采样率。
使用正确的参数创建新的AudioBuffer对象后,您只需将已保存的数组(recorded
数组)复制到AudioBuffer的通道数据数组中。这是一个相当简单的两步过程:
getChannelData(channel)
方法recorded
数组并通过.set(array, offset)
方法将保存的数据复制到频道数据数组中(有关详细信息,请参阅the MDN Float32Array docs)。您的代码看起来像channelData.set(currArray, currOffset)
,currOffset
增加了每个存储数组的长度。注意:如果您正在录制两个音频通道,您将拥有两个录制样本数组,您必须为每个通道执行上述两个步骤(0和1) ,复制相应的数组。
如果操作正确,您将拥有一个AudioBuffer,您可以将其插入AudioBufferSourceNode并根据需要进行播放。