Files
MetaCrate/docs/webrtc.md
Chili Palmer 66f10baa1b
Some checks failed
Native code generation / deterministic (push) Failing after 2m5s
Imaging and meshing gate / native (push) Failing after 5m37s
JPEG 2000 feature / linux (push) Successful in 2m49s
Native Rust workspace compile / compile (push) Failing after 17m32s
Skia feature / linux (push) Successful in 31m32s
Implement native WebRtcTest validation (#96)
2026-08-11 15:46:30 +00:00

3.9 KiB

Native WebRTC voice validation

The libremetaverse-voice-webrtc native API owns the complete WebRTC voice path. WebRtcVoiceSession::connect binds a caller-selected interface, creates an Opus send/receive m-line and ordered SLData channel, posts the grid's provision body through a VoiceSignaling implementation, applies the SDP answer, and drives ICE, DTLS, SRTP, RTP, and SCTP from a single async run loop. There is no CLR, C# process, RPC bridge, proprietary SDK, or platform-specific fallback.

The grid wire shapes match the viewer protocol:

  • Initial provisioning uses jsep.type=offer, channel_type=local, and voice_server_type=webrtc, with an optional top-level parcel_local_id.
  • ICE completion uses the singular candidate: { completed: true } field and the opaque viewer-session ID.
  • Teardown sends logout=true, then disconnects and joins the local peer loop.

Capability URLs, SDP, channel credentials, login secrets, and viewer-session credentials are not printed. VoiceSecret always formats as <redacted>. Incoming SDP and SLData messages are bounded and validated before use.

Deterministic validation

webrtc-test --fake is the CI path. LoopbackSignaling accepts the real offer, creates a second native peer, and exchanges UDP ICE checks, DTLS, encrypted Opus RTP, and SCTP SLData on loopback. It publishes peer audio/position and mute/gain maps; the client replies with join, mute, clamped gain, position, ping/pong, and leave. A generated virtual 48 kHz tone is encoded with libopus, echoed by the remote peer, decoded into the virtual sink, and counted. Shutdown awaits both peers and reports zero peer/audio tasks.

WAV playback accepts bounded integer or float PCM, downmixes all channels, linearly resamples to 48 kHz mono, encodes 20 ms Opus frames, and paces them on the same peer loop. This keeps virtual-audio tests deterministic and prevents orphan playback tasks.

Native prerequisites

The default virtual path requires native libopus development files at build time. Typical packages are:

  • Ubuntu/Debian: libopus-dev (and pkg-config).
  • Fedora: opus-devel.
  • Windows MSVC: audiopus supplies supported prebuilt Opus libraries; a custom libopus can be selected with OPUS_LIB_DIR/LIBOPUS_LIB_DIR.
  • macOS: install opus with the system package manager when it is not already discoverable by pkg-config.

Real hardware is separately opt-in. Build the program with --features real-audio; CPAL uses ALSA on Linux, WASAPI on Windows, and CoreAudio on macOS. Linux builders need ALSA development headers (for example libasound2-dev). List stable endpoint IDs with webrtc-test --list-devices, then pass --input-device cpal:input:... and/or --output-device cpal:output:.... Selected capture and render streams are opened only during the session and dropped after the peer loop is joined.

Live grid gate

Credential-only capability validation:

webrtc-test --allow-live-login --confirm-live-login LOGIN

The command reads GRID_USER="First Last", GRID_PASSWORD, and GRID_LOGIN_URL from the process environment or the workspace .env, matching the compatibility-test convention. Positional names/password and the legacy GRID_FIRST_NAME/GRID_LAST_NAME pair remain supported. Merely having a credential file never permits a login: both command-line confirmations above are still mandatory.

Creating a live voice session and sending/receiving media requires the separate --allow-session-audio flag. --bind-ip can select the concrete interface advertised in the host ICE candidate; otherwise the program discovers the preferred route without sending a packet. --wav FILE starts looping microphone playback. Interactive commands preserve the upstream tool's peers, mute, gain, playwav, stopwav, and quit controls; --commands FILE supplies the same commands non-interactively. Grid logout and voice teardown run even when the validation body fails.