Architecture
The page keeps capture, codecs and playback. The engine keeps the network, audio processing and the playout clock. Tauri IPC carries encoded video and PCM audio between them.
The shim
guest-js/shim.js is plain ES2020 with no dependencies. The plugin registers it as an initialization script on every frame, so it runs before page scripts. It installs itself only when the webview has no RTCPeerConnection of its own and the engine started.
Every object the shim hands out is a handle to a resource in the engine. W3C state (signalling state, transceiver directions, data channel ready state) lives in the shim, and changes as the engine's events arrive. Engine errors come back as DOMExceptions with the W3C name.
IPC
- Commands go through
invoke: create, negotiate, add candidates, data channel operations, stats. - Outgoing media goes through
invokeas raw bytes: encoded video frames, and audio PCM in batches. - Events and incoming media come back on one ordered channel per peer connection. Ordering matters:
icecandidate, state changes,datachanneland messages must reach the page in the order the engine produced them.
How media flows
Video
- The page captures frames from the track through a hidden
<video>. - WebCodecs encodes them, VP8 or H.264, at the bitrate the engine's bandwidth estimate allows.
- The engine packetizes, encrypts and sends them.
- On receive, the engine reassembles frames and sends them to the page.
- WebCodecs decodes them into a canvas. The canvas's
captureStream()is the remote track.
Camera tracks send at up to 1280×720 and 30 fps. Screen tracks, recognised by displaySurface or a detail or text content hint, send at up to 1920×1080 and 15 fps, with a bitrate of at least 1.5 Mbps. Keyframe requests from the far side reach the encoder.
Audio
- An AudioWorklet takes 48 kHz PCM from the microphone track and sends it to the engine.
- The engine runs echo cancellation, noise suppression and AGC, then Opus with in-band FEC.
- Received audio goes through a jitter buffer and one playout clock for all receivers.
- PCM comes back to an AudioWorklet that feeds the remote track.
The echo canceller needs the audio being played as its reference, which is why audio is processed in the engine rather than in the page.
The engine
qrtc is a separate crate. Its site covers the driver design, the features in depth and the vendored str0m and DTLS patches. The plugin talks to it through the PeerEngine and Peer traits, so Builder::engine can put another implementation behind the same shim.