Skip to content

Audio/video streaming over core/webrtc, relay resilience, overlay-network (Tailscale) reachability #35

Description

@Mearman

Parent: #28

Conversational reasoning grounded in the already-settled core/webrtc and relay-hub designs. Same honest status as #33/#34 for the parts flagged "not designed."

Audio/video streaming

  • One-way/two-way: already architecturally supported, zero spec changes. core/webrtc's signaling carries raw SDP opaquely — same offer/answer/ICE exchange for data channels and media tracks. Client-side work only (pc.addTrack()/pc.ontrack in webrtc-negotiation.ts); webrtc:signal gating already covers it.
  • Small-group via mesh: already supported via core/room membership + repeated pairwise core/webrtc negotiation, using relay-hub: multi-party fan-out fix + relay as an opt-in capability, not a deployed role #30's multi-pairing fix through a shared relay. Ceiling is WebRTC's own mesh topology, not wire-mesh's.
  • Larger-group (SFU/MCU): NOT supported — genuinely new, media-aware relay infrastructure, tracked as its own deferred item below.

Relay resilience

relay-hub is control-plane only — once ICE completes, media flows over WebRTC's own transport, so a relay going down mid-call doesn't affect an established call. Retry-on-failure resolved: ordinary connection-attempt handling, try candidates in the order handle-record/gossip lists them.

Overlay networks (Tailscale etc.)

Already transparently supported by the address-agnostic candidate design — a Tailscale address is just one more candidate, no Tailscale-aware code needed. Real gap: gossip's addresses field is currently shipped empty; the schema supports real candidate addresses, the code to populate and attempt them doesn't exist yet (tracked as a deferred item).

Two-network-bridged-by-one-link scenario

Signaling and media don't share a fate. Route signaling through whichever node opts into relaying (per #30) and has reachability into both networks — this works. Media does NOT follow automatically: a pair with no real underlying network route will never find a working ICE candidate regardless of signaling success. Making media cross the gap needs an SFU at the bridge point (same deferred item as above), not N independently-relayed pairs.


One-way/two-way audio/video client-side work done (2026-09-14, wire-mesh#136): localTracks/onRemoteTrack added to WebrtcNegotiatorOptions, wired into both initiate() and handleIncomingOffer() via a shared wireMediaTracks() helper -- no wire-protocol change, exactly as this issue's own text anticipated. Proven end-to-end, not just unit-tested: the live-check Playwright harness now drives two independent Chromium instances with synthetic (--use-fake-device-for-media-stream) getUserMedia tracks through a real wire-mesh-node relay, confirming both sides receive the other's real audio and video tracks over the same offer/answer/ICE exchange the data channel already used.

Still open within this issue's own scope: the SFU/MCU larger-group case (genuinely new, media-aware relay infrastructure) and populating real gossip candidate addresses (wire-mesh#38, fork 1 of which is separately resolved in wire-mesh#135 -- fork 2, populating from a real listener, remains blocked on a real listen-and-dial consumer). Relay resilience and overlay-network reachability were already correctly described as needing no further code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions