replace deprecated ScriptProcessorNode with AudioWorklet

This commit is contained in:
Quentin Fuxa 2025-09-16 23:31:00 +02:00
parent 2a27d2030a
commit 4d7c487614
2 changed files with 41 additions and 13 deletions

View file

@ -12,7 +12,7 @@ let timerInterval = null;
let audioContext = null; let audioContext = null;
let analyser = null; let analyser = null;
let microphone = null; let microphone = null;
let scriptProcessor = null; let workletNode = null;
let recorderWorker = null; let recorderWorker = null;
let waveCanvas = document.getElementById("waveCanvas"); let waveCanvas = document.getElementById("waveCanvas");
let waveCtx = waveCanvas.getContext("2d"); let waveCtx = waveCanvas.getContext("2d");
@ -459,9 +459,12 @@ async function startRecording() {
microphone = audioContext.createMediaStreamSource(stream); microphone = audioContext.createMediaStreamSource(stream);
microphone.connect(analyser); microphone.connect(analyser);
scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1); if (!audioContext.audioWorklet) {
microphone.connect(scriptProcessor); throw new Error("AudioWorklet is not supported in this browser");
scriptProcessor.connect(audioContext.destination); }
await audioContext.audioWorklet.addModule("/web/pcm_worklet.js");
workletNode = new AudioWorkletNode(audioContext, "pcm-forwarder", { numberOfInputs: 1, numberOfOutputs: 0, channelCount: 1 });
microphone.connect(workletNode);
recorderWorker = new Worker("/web/recorder_worker.js"); recorderWorker = new Worker("/web/recorder_worker.js");
recorderWorker.postMessage({ recorderWorker.postMessage({
@ -477,12 +480,16 @@ async function startRecording() {
} }
}; };
scriptProcessor.onaudioprocess = (e) => { workletNode.port.onmessage = (e) => {
const inputData = e.inputBuffer.getChannelData(0); const data = e.data;
recorderWorker.postMessage({ const ab = data instanceof ArrayBuffer ? data : data.buffer;
command: "record", recorderWorker.postMessage(
buffer: inputData.buffer, {
}, [inputData.buffer]); command: "record",
buffer: ab,
},
[ab]
);
}; };
startTime = Date.now(); startTime = Date.now();
@ -526,9 +533,14 @@ async function stopRecording() {
recorderWorker = null; recorderWorker = null;
} }
if (scriptProcessor) { if (workletNode) {
scriptProcessor.disconnect(); try {
scriptProcessor = null; workletNode.port.onmessage = null;
} catch (e) {}
try {
workletNode.disconnect();
} catch (e) {}
workletNode = null;
} }
if (microphone) { if (microphone) {

View file

@ -0,0 +1,16 @@
class PCMForwarder extends AudioWorkletProcessor {
process(inputs) {
const input = inputs[0];
if (input && input[0] && input[0].length) {
// Forward mono channel (0). If multi-channel, downmixing can be added here.
const channelData = input[0];
const copy = new Float32Array(channelData.length);
copy.set(channelData);
this.port.postMessage(copy, [copy.buffer]);
}
// Keep processor alive
return true;
}
}
registerProcessor('pcm-forwarder', PCMForwarder);