siyuan-note/siyuan · error · Error
AudioWorklet is not supported
Error message
AudioWorklet is not supported
What it means
After successfully creating an AudioContext, the constructor verifies both context.audioWorklet and the global AudioWorkletNode exist; if either is missing it throws 'AudioWorklet is not supported'. AudioWorklet is the modern (post-2018) replacement for ScriptProcessorNode and is required for the recorder's chunked Int16 capture path.
Source
Thrown at app/src/protyle/util/RecordMedia.ts:104
private failure: Error;
private readonly handleTrackEnded = () => {
this.handleWorkerError(new RecordMediaInputEndedError());
};
constructor(mediaStream: MediaStream) {
this.mediaStream = mediaStream;
const AudioContextConstructor = typeof AudioContext !== "undefined" ? AudioContext : webkitAudioContext;
if (!AudioContextConstructor) {
throw new Error("AudioContext is not supported");
}
const contextOptions = {} as AudioContextOptions & { sinkId?: { type: "none" } };
if ((isInAndroid() || isInHarmony()) && "setSinkId" in AudioContextConstructor.prototype) {
contextOptions.sinkId = {type: "none"};
}
this.context = new AudioContextConstructor(contextOptions);
if (!this.context.audioWorklet || typeof AudioWorkletNode === "undefined") {
throw new Error("AudioWorklet is not supported");
}
this.audioInput = this.context.createMediaStreamSource(mediaStream);
this.mediaStream.getAudioTracks().forEach((track) => {
track.addEventListener("ended", this.handleTrackEnded);
});
}
public async startRecording() {
if (this.disposed) {
throw new Error("Recorder has been disposed");
}
if (this.isRecording) {
return;
}
this.chunks = [];
this.readyPromise = new Promise<void>((resolve, reject) => {
this.resolveReady = resolve;View on GitHub (pinned to 251596fc0d)
Solutions
- Feature-detect context.audioWorklet and typeof AudioWorkletNode before constructing RecordMedia; hide the record button if unsupported.
- Upgrade the host browser/webview to a version with AudioWorklet (Chrome 66+, Firefox 76+, Safari 14.1+).
- If you must support older engines, fall back to a ScriptProcessorNode-based recorder (not implemented here).
- In automated tests, use standardized-audio-context which provides an audioWorklet mock.
Example fix
// before
const rec = new RecordMedia(stream);
// after
const ctx = new (window.AudioContext || window.webkitAudioContext)();
if (!ctx.audioWorklet || typeof AudioWorkletNode === 'undefined') {
showMessage('Voice recording needs a newer browser (AudioWorklet unsupported).');
ctx.close(); return;
} Defensive patterns
Strategy: type-guard
Validate before calling
const Ctor = typeof AudioContext !== 'undefined' ? AudioContext : (window as any).webkitAudioContext;
const tmp = new Ctor();
const ok = !!tmp.audioWorklet && typeof AudioWorkletNode !== 'undefined';
tmp.close();
if (!ok) { disableRecordButton(); } Type guard
function audioWorkletSupported(): boolean {
const Ctor = typeof AudioContext !== 'undefined' ? AudioContext : (window as any).webkitAudioContext;
if (!Ctor) return false;
const c = new Ctor();
const ok = !!c.audioWorklet && typeof AudioWorkletNode !== 'undefined';
c.close();
return ok;
} Try / catch
try { recorder = new RecordMedia(stream); }
catch (e) { if (/AudioWorklet/i.test(e.message)) showMessage('Update your browser to use voice recording'); } Prevention
- Detect audioWorklet + AudioWorkletNode before constructing RecordMedia.
- Require Chrome 66+/Safari 14.1+/Firefox 76+ for recording.
- Disable the record button rather than throwing on unsupported clients.
- Polyfill AudioWorklet in tests with standardized-audio-context mock.
When it happens
Trigger: Running on a browser/webview that has Web Audio but predates AudioWorklet (Chrome <66, Safari <14.1, old WebViews), or where the user disabled the worklet feature flag, or in a context where AudioWorkletNode global is not exposed.
Common situations: Old iOS Safari (<14.1); legacy Electron build; embedded webview shipped with an old Chromium; privacy extension stripping AudioWorklet globals.
Related errors
- AudioContext is not supported
- Recorder has been disposed
- MP3 encoder is not initialized
- Canvas 2D is unavailable
- WebGL2 is unavailable
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/9dd9b76e7f93d9f7.
Report an issue: GitHub.