copy/v86 · warning

Web browser doesn't support Web Audio API

Error message

Web browser doesn't support Web Audio API

What it means

SpeakerAdapter (src/browser/speaker.js:30) checks for window.AudioContext or window.webkitAudioContext before constructing a DAC (AudioWorklet or BufferSource based). If neither exists, the browser does not implement the Web Audio API, v86 logs this warning and returns — no audio output is created, but emulation continues. It is a capability warning, not an exception.

Source

Thrown at src/browser/speaker.js:30

/* global registerProcessor, sampleRate */

const DAC_QUEUE_RESERVE = 0.2;

const AUDIOBUFFER_MINIMUM_SAMPLING_RATE = 8000;

/**
 * @constructor
 * @param {!BusConnector} bus
 */
export function SpeakerAdapter(bus)
{
    if(typeof window === "undefined")
    {
        return;
    }
    if(!window.AudioContext && !window["webkitAudioContext"])
    {
        console.warn("Web browser doesn't support Web Audio API");
        return;
    }

    var SpeakerDAC = window.AudioWorklet ? SpeakerWorkletDAC : SpeakerBufferSourceDAC;

    /** @const */
    this.bus = bus;

    this.audio_context = window.AudioContext ? new AudioContext() : new webkitAudioContext();

    /** @const */
    this.mixer = new SpeakerMixer(bus, this.audio_context);

    /** @const */
    this.pcspeaker = new PCSpeaker(bus, this.audio_context, this.mixer);

    this.dac = new SpeakerDAC(bus, this.audio_context, this.mixer);

View on GitHub (pinned to 180830d539)

Solutions

  1. Upgrade to a modern browser that implements the Web Audio API (any current Chrome, Firefox, Safari, Edge)
  2. If embedding (Electron/webview), ensure Web Audio is enabled and autoplay policy permits audio (configure autoplay policy flags)
  3. Guard your integration: check (window.AudioContext || window.webkitAudioContext) before requesting speaker output and skip audio gracefully
  4. If audio is optional, ignore the warning — v86 continues running without sound

Example fix

// before
new V86({ wasm_path, screen_container, speaker: true });
// after
if(window.AudioContext || window.webkitAudioContext)
{
    new V86({ wasm_path, screen_container, speaker: true });
}
else
{
    new V86({ wasm_path, screen_container }); // run without audio
}
Defensive patterns

Strategy: fallback

Validate before calling

function supportsWebAudio()
{
    return typeof window !== 'undefined' && !!(window.AudioContext || window.webkitAudioContext);
}
// Only pass speaker: true if supportsWebAudio() returns true

Type guard

function hasAudioContext(win = window)
{
    return typeof win.AudioContext === 'function' || typeof win['webkitAudioContext'] === 'function';
}

Try / catch

// Not an exception, but guard construction anyway
try
{
    if(hasAudioContext()) { new V86({ ..., speaker: true }); }
    else { new V86({ ... }); } // silent fallback: no speaker option
}
catch(e) { console.error('v86 init failed:', e); }

Prevention

When it happens

Trigger: Instantiating SpeakerAdapter (e.g. via V86's autostart/speaker options) in a runtime where window exists but has neither AudioContext nor webkitAudioContext — old browsers, some webviews, or non-browser embeddings that define window without Web Audio.

Common situations: Running v86 in an outdated browser (pre-2015 Safari/IE-based webviews); embedding v86 in Electron/WebView builds with Web Audio disabled or removed; headless or sandboxed environments that stub window but not AudioContext; feature detection failing after a browser policy disabled audio.

Related errors


AI-assisted analysis of copy/v86@180830d539 (2026-08-31). Data as JSON: /api/errors/f570a4c1d20340de. Report an issue: GitHub.