我想对麦克风输入进行一些实时处理(包括下采样),最重要的是我想保存输入样本。
在将代码部署到生产环境后,我注意到我收到的一些录音有问题,有些录音比其他录音要多得多。故障是指记录包含零值样本的随机周期。该问题发生在 Android 设备上。
幸运的是,我得到了一台能够始终如一地重现该问题的设备(OnePlus 6)。在将 AudioWorklet 剥离到最低限度后,我仍然可以观察到故障。这就是我的测试 AudioWorklet 类在去掉通信部分后的样子。
class TestWorklet extends AudioWorkletProcessor {
constructor(options) {
super(options);
// Allocate the buffer once in the beginning
this.recordingBuffer = new Float32Array(sampleRate * 20); // store max 20 sec audio
this.recordingBufferOffset = 0;
}
process(inputs, outputs) {
const input = inputs[0];
const output = outputs[0];
// Copy samples to the recording buffer
if (this.recordingBufferOffset < this.recordingBuffer.length - input[0].length) {
this.recordingBuffer.set(input[0], this.recordingBufferOffset);
this.recordingBufferOffset += input[0].length;
}
// Copy input to the output
for (let channel = 0; channel < input.length; ++channel) {
output[channel].set(input[channel]);
}
return true;
}
}
registerProcessor('TestWorklet', TestWorklet);
为了完整起见,这就是我连接 AudioWorklet 的方式
import TestWorklet from './testWorklet';
start = async () => {
let stream;
let audioCtx;
if (navigator.mediaDevices) {
try {
stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
} catch (e) { }
}
if (!stream) {
return false;
}
try {
audioCtx = new AudioContext();
} catch (e) {
return false;
}
await audioCtx.audioWorklet.addModule(TestWorklet);
const audioSource = audioCtx.createMediaStreamSource(stream);
const worklet = new AudioWorkletNode(audioCtx, "TestWorklet", {
channelCount: 1,
channelCountMode: "explicit",
channelInterpretation: "discrete"
});
audioSource.connect(worklet);
await audioCtx.resume();
return true;
}
有趣的是,在功能较弱的 Android 设备上,我没有遇到这些零故障。至少我没有注意到。
有没有人有这个问题的经验?也许我正在使用次优参数初始化 Worklet?
同时,我正在尝试使用已弃用的替代实现ScriptProcessorNode
来查看它是否表现更好。