supervision-js
    Preparing search index...

    Browser Support

    Four things the browser path does not do. None of them is a defect, and each surfaces the same way every time.

    In Firefox 154, WebCodecs reported the tested hvc1 and hev1 configurations unsupported even though the same HEVC file played in a <video> element. The built-in URL/File source therefore fails to open that file.

    The failure is at load, not at a frame. Opening the source asks the browser whether it can decode the track, and a refusal raises DecodeUnsupported with the codec string in the message before any frame is presented. An application that accepts arbitrary uploads should handle that error and offer H.264 or VP9 instead.

    This is that decoder rather than a rule about non-Chromium browsers. Safari 18.6 reports hvc1 and hev1 supported alongside avc1, vp8, vp09 and av01, and plays the same file.

    The built-in URL/File source decodes through WebCodecs and has no software decoder fallback. Advanced hosts can provide their own PresentedFrameChannel, but then own decoding, frame selection, and presentation acknowledgement.

    Where WebGPU is available and its queue accepts the selected sample path, the frame goes straight into the texture the scene samples. Eligible Android H.264 decoder-session output may first be materialized into independently owned pixels before WebGPU performs the final upload. Where direct upload is not available, every presented frame is drawn into a media-sized 2D canvas and that whole canvas is uploaded into the sprite's texture.

    Two browsers take the second path today, for different reasons:

    • Safari exposes no WebGPU at all, in the page or in a worker, so the scene finds no device to ask.
    • Firefox exposes WebGPU whose queue takes only ImageBitmap, HTMLImageElement, HTMLCanvasElement and OffscreenCanvas, and rejects a decoded frame. The scene asks once when it is built and routes the frames through the staging canvas rather than letting each present fail.

    On the tested Safari 18.6/reference-Mac route, staging ran once per presented frame and dominated the recorded playback wall time. The same frames uploaded straight into a WebGL texture in that browser cost a small fraction of that. This is a scoped measurement, not a cross-device browser guarantee. Part of the gap is per-pixel work, and part is that the staging surface is media-sized whatever the decode delivers, so a decode below media size is drawn back up before it is uploaded.

    Nothing is lost, and no application has to opt in or out. What it costs is headroom, so a heavy annotation load on a large clip has less of it in these browsers than in Chrome.

    Nothing in the package decodes or plays audio, on any source. The engine walks video tracks only, and normalization discards audio by default (audio.discard).

    MediaSessionRendererOptions.muted is deprecated because nothing reads it. It is still accepted, and setting it changes nothing either way. Media that carries an audio track still opens and plays; the track is ignored.

    Opening a source walks its packets metadata-only to build the table that gives every frame an identity, and that walk is eager: it finishes before the first frame is presented. Past one million frames the load fails with DecodeUnsupported rather than playing without frame identity.

    At 30 fps the cap is about nine hours of video, so an ordinary file never reaches it. What reaches it is an endless stream or a heavily fragmented container. For scale, a 70-second 30 fps source walks 2113 packets in a measured 5.7 ms.

    An application that needs to render sources longer than the cap needs a different frame-addressing scheme than the one this package provides.