siyuan-note/siyuan · error
AudioContext is not supported
Error message
AudioContext is not supported
What it means
The RecordMedia constructor needs an AudioContext (or webkitAudioContext) to analyze the microphone stream. If neither global exists in the runtime, it throws 'AudioContext is not supported'. The environment cannot provide the Web Audio API required for recording.
Solutions
- Serve the app over HTTPS (or localhost) so the Web Audio API is available
- Update the platform's webview/browser to a version supporting AudioContext
- Catch this error in the recording UI and show 'recording not supported in this environment' instead of crashing
- Feature-detect typeof AudioContext === "undefined" before attempting to record and hide the record button
Example fix
// before
const recorder = new RecordMedia(stream);
// after
if (typeof AudioContext === "undefined" && typeof webkitAudioContext === "undefined") {
showMessage(window.siyuan.languages.audioNotSupported);
return;
}
const recorder = new RecordMedia(stream); Defensive patterns
Strategy: fallback
Validate before calling
const audioSupported = typeof AudioContext !== "undefined" || typeof webkitAudioContext !== "undefined";
Type guard
const hasAudioContext = (): boolean => typeof (window as any).AudioContext !== "undefined" || typeof (window as any).webkitAudioContext !== "undefined";
Try / catch
let recorder: RecordMedia | null = null;
try {
recorder = new RecordMedia(stream);
} catch (e) {
if (e.message === "AudioContext is not supported") {
showMessage("Recording is not supported in this environment");
return;
}
throw e;
} Prevention
- Serve the app over HTTPS or localhost
- Feature-detect AudioContext before showing the record button
- Keep embedded webviews updated
- Gate recording behind a capability check at app startup
When it happens
Trigger: Instantiating RecordMedia with a MediaStream in an environment where both AudioContext and webkitAudioContext are undefined — e.g. a non-secure (http) page where Web Audio is unavailable, an old webview, or a very old browser.
Common situations: Recording feature used inside an outdated embedded webview; page served over plain HTTP so some audio APIs are restricted; very old Android System WebView; SSR/test environment lacking browser globals.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/8f9decceb9010b7e.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/protyle/util/RecordMedia.ts:95
private worker: Worker;
private chunks: ArrayBuffer[] = [];
private readyPromise: Promise<void>;
private resolveReady: () => void;
private rejectReady: (error: Error) => void;
private stopPromise: Promise<Blob>;
private resolveStop: (blob: Blob) => void;
private rejectStop: (error: Error) => void;
private disposed = false;
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) {View on GitHub (pinned to 9f775e8a12)