Browser (WebAssembly)
The nc-web crate compiles our encoders and decoders to WebAssembly with
wasm-bindgen. The demo runs on this
module; so can your page. Every codec the native build has is in it.
Build the module
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.105 --locked
tools/web/build.sh # writes web/pkg/ and web/pkg/relaxed/
Each directory holds nc_web.js (an ES module) and nc_web_bg.wasm. The two builds
give bit-identical output: pkg/ uses SIMD128, pkg/relaxed/ adds relaxed SIMD.
web/wasm.js picks the relaxed build where WebAssembly.validate accepts a
relaxed-SIMD probe, else the plain one.
Browser support
- WebAssembly SIMD128 is required. Both modules are compiled with it, and an engine without
it rejects the module:
init()fails. Chrome and Edge 91, Firefox 89 and Safari 16.4 were the first versions with SIMD128. - Our tests run the module in headless Chromium only. Other engines are expected to work where they support SIMD128, but we have not tested them.
- The browser encoder accepts sizes from 64x64 to 1920x1080 and up to 60 fps. Encoding and decoding are single-threaded per instance; the demo runs each encoder and decoder in its own Web Worker.
The JavaScript API
await init(), the module's default export, loads and instantiates the WebAssembly file next tonc_web.js. A page that starts several workers can compile the module once and pass theWebAssembly.Moduleto each, asweb/wasm.jsdoes (init({ module_or_path })).new SourceFrame(width, height)holds an input frame; fill it withfrom_rgba(rgba)(canvas pixels) orfrom_planes(...)(a WebCodecsVideoFrame's YUV planes).new BrowserEncoder(codec, width, height, qp, fps, keyInterval, preset, overrides, filmGrain, colour, stillCamera, spatialLayers)creates a fixed-QP encoder (overrides, colour, stillCamera and spatialLayers may be undefined; the preset is a rung of the ladder);set_rate_control(targetKbps, peakKbps, bufferMs)switches it to real-time rate control.encode(source)(orencode_at(source, timestampUs)for a live source) returns the packet as aUint8Array;repeatis true when nothing was coded.request_keyframe()asks for a key frame.new BrowserDecoder(codec);decode_frame(packet, index, references)returns an outcome (decoded, or the freezereason).rgba_frame(colour)andi420_frame()return an offset intomemory.bufferwhere the picture is.- A call into the module may grow its memory, which detaches earlier views of
memory.buffer: take the offset first, then make the view and copy from it at once.
Minimal standalone page
Draws a moving picture on a canvas, encodes it with H.264 at 300 kbps, decodes every packet and draws the
decoded picture beside the source. It loads the demo's module from ../../pkg/:
run it here. To use it elsewhere, copy it next to a
pkg/ directory from the build and change the import path; serve it over HTTP, as browsers do not
load modules from file:// pages.
Loading…