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

  1. Feature-detect context.audioWorklet and typeof AudioWorkletNode before constructing RecordMedia; hide the record button if unsupported.
  2. Upgrade the host browser/webview to a version with AudioWorklet (Chrome 66+, Firefox 76+, Safari 14.1+).
  3. If you must support older engines, fall back to a ScriptProcessorNode-based recorder (not implemented here).
  4. 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

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


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/9dd9b76e7f93d9f7. Report an issue: GitHub.