WHIP publishing¶
media.publish.whip
A sender connects to Sapsan over WHIP and publishes into a regular publish input. Received frames enter the shared media pipeline; configure archive recording and other playback protocols separately.
Configuration¶
Set these options through central. Streamer configuration example:
listeners:
http:
- port: 8080
auth:
publish_tokens:
- PUBLISH_TOKEN
streams:
- name: studio
inputs:
- publish: {}
listeners.webrtc sets shared UDP ports for WHIP and WHEP. If omitted or empty, the OS selects one free port. port: 0 also enables automatic selection. SDP ICE candidates announce the bound port; there is no dedicated port per session. Reapplying an unchanged list preserves the selected port. A restart may change it.
| Parameter | Value | Behavior |
|---|---|---|
listeners.webrtc |
Omitted or [] |
One automatic UDP port |
listeners.webrtc[].port |
Required per entry, 0–65535 |
0 selects a port automatically; a non-zero value fixes it |
listeners:
webrtc:
- port: 5005
- port: 5006
For fixed firewall rules or forwarding behind NAT, set ports explicitly and make them reachable by clients. The HTTP proxy handles SDP signaling; UDP media must reach the streamer itself. The ICE address is detected from local IPv4 routing; listeners.webrtc has no public ICE address or TURN setting. Automatic port selection does not configure NAT.
Publishing URL¶
Direct streamer URL:
https://streamer.example.com/streaming/whip/studio
Authentication¶
Send Authorization: Bearer PUBLISH_TOKEN or ?token=PUBLISH_TOKEN. Configure admission with auth.publish_tokens or an authorization backend. Publishing and viewing permissions are configured separately.
Transport¶
HTTP(S) handles SDP negotiation and session control. Media uses UDP with ICE and DTLS-SRTP/SRTCP. Use HTTPS in a browser; HTTP listener access and media UDP port access are separate requirements.
If the browser page and WHIP/WHEP endpoint use different origins, add the response header Access-Control-Expose-Headers: Location at the HTTPS proxy so the client can read the created session URL. This is unnecessary when the page and API share an origin.
Supported codecs¶
- H.264
- AV1
- Opus
Video is H.264 or AV1; audio is Opus. H.264 is preferred during negotiation; WHEP also depends on the source codecs and player capabilities. WebRTC does not transcode: convert other audio codecs to Opus beforehand. This media path does not support HEVC or VP8/VP9. WHEP requires a supported video track; audio is optional.
HTTP API¶
| Method and path | Result |
|---|---|
POST /streaming/whip/{stream} |
SDP offer (application/sdp); returns 201 Created, an SDP answer and the session URL in Location |
GET /streaming/whip/{stream} |
204 No Content; returns neither video nor a player page |
OPTIONS /streaming/whip/{stream} |
CORS and accepted content types |
DELETE /streaming/whip/session/{id} |
Close the session; returns 204 No Content |
PATCH /streaming/whip/session/{id} |
An accepted non-empty SDP fragment receives 501 Not Implemented |
The offer must include all client ICE candidates: adding candidates later through PATCH is unsupported. Save the response Location and use it to close the session. The server answers recvonly for WHIP and sendonly for WHEP.
Error handling¶
| Code | Cause |
|---|---|
400 |
Malformed SDP or an offer that cannot be negotiated |
403 |
Access denied; WHEP also refuses encrypted content |
404 |
Stream is not running; WHEP also requires available track information |
409 |
WHIP: no publish input or an existing active publisher |
415 |
Incorrect Content-Type; WHEP also requires a supported video track |
503 |
Failed to register a media route; a WHEP viewer group may also be temporarily unavailable |
A stream accepts one active WHIP publisher. The sender reconnects after disconnection; input failover determines subsequent stream behavior.
Limitations¶
Initial offer/answer signaling includes all ICE candidates. Trickle ICE, ICE restart, WHEP counter-offers and TCP fallback are not implemented. Changing the UDP listener list rebuilds the transport: reconnect existing clients. An unchanged list keeps the working sockets.