WebRTC / WHIP publishing

Choose WebRTC / WHIP in a stream's output target dialog. Enter the HTTP(S) publishing endpoint provided by your receiver and, when needed, its bearer token. This publishes video and optional KLV; audio forwarding is not supported. The endpoint is not a playback URL. Viewer delivery belongs to the receiver.

WHIP requires Recast. Select Original source or an eligible existing Flywheel processor; the latter also requires Flywheel. Multiple WHIP endpoints can run alongside UDP, SRT, LL-HLS, and browser playback. Each publisher is independently supervised and retries failures without stopping the other outputs.

Video and metadata

Passthrough defaults to H.264 and requires the source codec to match the selected receiver codec. VP8 and VP9 passthrough additionally require the SDK's matching parser plugins. H.265 requires Transcode. Transcoding supports H.264, VP8, and VP9 and adds an encoder. Processor targets receive the existing Flywheel MPEG-TS feed; they do not start another compositor. Transcoding is never enabled silently.

Transcode settings expose bitrate, maximum bitrate, keyframe interval, rate control, and hardware preference. Zero numeric values use SDK defaults. The hardware preference allows software fallback.

KLV defaults to Raw + JSON, with video-only fallback when the receiver rejects data channels. Use Require KLV data channels to fail instead, or disable KLV for receivers that reject offers containing data channels. An empty PID list allows every discovered KLV PID. Raw channels use the SDK's SVKL envelope; JSON channels use its MISB metadata envelope. Generic WebRTC players do not automatically display these channels.

Output status shows connection state, codec, encoder, HTTP status, KLV negotiation and counters. Bitrate comes from measured SDK output counters; unavailable counters are explicitly identified and do not make a connected publisher appear offline. Public status excludes bearer tokens, endpoint paths/queries, and session URLs.

Configuration example

{
  "id": "publish",
  "inputType": "source",
  "engines": [{
    "type": "whip",
    "config": {
      "url": "https://receiver.example/live/camera/whip",
      "whipVideoMode": "transcode",
      "whipVideoCodec": "h264",
      "whipVideoBitrateKbps": 4000,
      "whipVideoMaxBitrateKbps": 6000,
      "whipVideoKeyframeInterval": 60,
      "whipRateControl": "vbr",
      "whipPreferHardwareEncoder": true,
      "whipKlvMode": "rawAndJson",
      "whipKlvPids": [258],
      "whipRequireKlv": false,
      "whipSignalingTimeoutMs": 10000
    }
  }]
}

Optional authentication is stored as whipBearerToken using the existing target configuration persistence. Authorized configuration reads and exports contain these settings, as with existing SRT credentials; public statistics do not.

Runtime and verification

Rebuild the server and native helper together: worker protocol 5 adds probeWHIP, mode: "whip", typed whipConfig, an accepted acknowledgement, and WHIP telemetry. Older workers are rejected. The acknowledgement precedes synchronous SDK negotiation so file/Pattern inputs can start feeding video. Only connected SDK state means publishing is running.

Failures retry with exponential backoff capped at 32 seconds, reset after a successful connection. A disconnected established session gets 30 seconds to recover. Stop requests graceful session deletion before forced process cleanup.

Builds require GStreamer WebRTC, SDP and RTP development libraries and libsoup 3.0 (or 2.4). Packaging probes the ICE, DTLS/SRTP, SCTP, payloaders, and supported transcode encoders. The worker's SDK logging is disabled by a local compatibility patch because native diagnostics otherwise write authenticated URLs to files and the Windows debugger. Sanitized worker protocol messages remain available.

The fetched SDK also receives a compatibility fix to recognize rejected SDP data-channel sections (port zero), so required-KLV negotiation fails correctly. These patches do not modify a sibling SDK checkout.

Run the Go suites for internal/whip, internal/streams, internal/flywheel, internal/app, and internal/api, and the frontend tests/build. Use the Windows test wrapper with SKY_VIEW_HOST_MEDIA set to a Windows path.

Set SKYVIEW_TEST_WHIP=1 and SKYVIEW_FLYWHEEL_WORKER to the rebuilt helper to run TestWHIPNativePublication, with gst-launch-1.0 on PATH. Its local authenticated Pion receiver checks RTP decoded into JPEG images, Pattern KLV raw/JSON delivery, H.264 passthrough, H.265 transcoding, VP8/VP9 encoding, and session DELETE. Native tests are opt-in; skipped tests do not establish platform coverage.

Release qualification also covers RTSP credentials/TCP/latency, file/PCAP replay, Flywheel feeds, receiver rejection/recovery, multiple simultaneous outputs, worker crashes, and shutdown on Windows and Linux. Browser playback must continue when a publishing target fails.