I recently developed a basic audio recorder that utilizes the AudioWorkletAPI. While the playback functions smoothly on Chrome, it seems to have issues on Safari and iPhone devices (including Chrome on iPhone) where half of the audio is missing. Specifically, only the first 20% and the last 30% of the audio can be heard.
You can check out the live example here:
Take a look at the audio worklet code below:
class RecorderProcessor extends AudioWorkletProcessor {
bufferSize = 4096;
// 1. Track the current buffer fill level
_bytesWritten = 0;
// 2. Create a buffer of fixed size
_buffer = new Float32Array(this.bufferSize);
constructor() {
super();
this.initBuffer();
}
initBuffer() {
this._bytesWritten = 0;
}
isBufferEmpty() {
return this._bytesWritten === 0;
}
isBufferFull() {
return this._bytesWritten === this.bufferSize;
}
process(inputs) {
// Grabbing the 1st channel similar to ScriptProcessorNode
this.append(inputs[0][0]);
return true;
}
append(channelData) {
if (this.isBufferFull()) {
this.flush();
}
if (!channelData) return;
for (let i = 0; i < channelData.length; i++) {
this._buffer[this._bytesWritten++] = channelData[i];
}
}
flush() {
// trim the buffer if ended prematurely
this.port.postMessage(
this._bytesWritten < this.bufferSize
? this._buffer.slice(0, this._bytesWritten)
: this._buffer
);
this.initBuffer();
}
}
registerProcessor('recorder.worklet', RecorderProcessor);
And here's the code responsible for initiating/stopping the recording and encoding it into WAV format:
let sampleRate = 3000;
// More code continues...