v0.4: Trickle-ICE on WHIP ingest handler #21

Closed
opened 2026-05-10 13:19:05 -04:00 by zgaetano · 0 comments
Owner

Problem

The current WHIP handler requires the publisher to send a complete SDP offer in the initial POST. OBS Studio (≥ 30.1) and most browser-based WHIP publishers use trickle-ICE: they send an incomplete SDP offer and then stream ICE candidates via PATCH requests as they are gathered.

Without trickle-ICE support, OBS and browser publishers stall waiting for ICE gathering to complete before sending the offer, which adds 1–3 s of setup latency and may time out on networks where gathering is slow.

Work

The WHIP spec (draft-ietf-wish-whip §4.4) defines:

  • POST /api/v3/whip/{id} — accepts an offer with a=ice-options:trickle and returns a 201 answer immediately (before ICE is fully gathered on the server side).
  • PATCH /api/v3/whip/{id}/{resource} — accepts application/trickle-ice-sdpfrag bodies containing individual ICE candidates, forwarded to pc.AddICECandidate(). Returns 204.
  • PATCH with an empty body (or a=end-of-candidates) signals the end of trickle.

app/webrtc/whip_handler.go — add a PATCH route; store the *webrtc.PeerConnection per resource ID so candidates can be forwarded; parse trickle-ice-sdpfrag fragments.

core/webrtc/peer.goCreatePeerFromSources currently blocks on GatheringCompletePromise before returning. Add a CreatePeerFromSourcesTrickle variant (or a flag) that returns immediately with an incomplete answer and completes gathering asynchronously.

app/webrtc/whip_handler.go — the POST handler should detect a=ice-options:trickle in the offer SDP and switch to the trickle path.

Tests — a TestWHIP_TrickleICE_* suite in whip_handler_test.go simulating a publisher that sends offer → PATCH candidates → final PATCH.

## Problem The current WHIP handler requires the publisher to send a complete SDP offer in the initial `POST`. OBS Studio (≥ 30.1) and most browser-based WHIP publishers use trickle-ICE: they send an incomplete SDP offer and then stream ICE candidates via `PATCH` requests as they are gathered. Without trickle-ICE support, OBS and browser publishers stall waiting for ICE gathering to complete before sending the offer, which adds 1–3 s of setup latency and may time out on networks where gathering is slow. ## Work The WHIP spec (draft-ietf-wish-whip §4.4) defines: - `POST /api/v3/whip/{id}` — accepts an offer with `a=ice-options:trickle` and returns a `201` answer immediately (before ICE is fully gathered on the server side). - `PATCH /api/v3/whip/{id}/{resource}` — accepts `application/trickle-ice-sdpfrag` bodies containing individual ICE candidates, forwarded to `pc.AddICECandidate()`. Returns `204`. - `PATCH` with an empty body (or `a=end-of-candidates`) signals the end of trickle. **`app/webrtc/whip_handler.go`** — add a `PATCH` route; store the `*webrtc.PeerConnection` per resource ID so candidates can be forwarded; parse `trickle-ice-sdpfrag` fragments. **`core/webrtc/peer.go`** — `CreatePeerFromSources` currently blocks on `GatheringCompletePromise` before returning. Add a `CreatePeerFromSourcesTrickle` variant (or a flag) that returns immediately with an incomplete answer and completes gathering asynchronously. **`app/webrtc/whip_handler.go`** — the `POST` handler should detect `a=ice-options:trickle` in the offer SDP and switch to the trickle path. **Tests** — a `TestWHIP_TrickleICE_*` suite in `whip_handler_test.go` simulating a publisher that sends offer → PATCH candidates → final PATCH.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: zgaetano/datarhei-dragonfork-core#21
No description provided.