v0.3: WHIP ingest path #16

Closed
opened 2026-05-03 14:54:30 -04:00 by zgaetano · 0 comments
Owner

WHIP Ingest — Implementation Complete

All four tasks are done and running in production.


What was built

Backend — Go (datarhei-dragonfork-core)

Commit File Change
4ac63dd app/api/api.go Added whiphandler *appwebrtc.WHIPHandler field; switched to MergedHooks() so WHIP lifecycle hooks register alongside WHEP; wired NewWHIPHandler into server config; added cleanup
4d94c88 http/api/process.go Added ProcessConfigWHIPIngest struct; added WHIPIngest field to ProcessConfig; wired Marshal() and Unmarshal() so the API accepts and returns whip_ingest.{enabled,video_pt,audio_pt}

Frontend — wilddragon-restreamer-ui overlay

Commit File Change
ab8432d overlay/src/misc/controls/WHIP.js New control component — enable checkbox bound to control.whip_ingest.enable, mirrors WHEP.js pattern
0f5163e overlay/src/views/Edit/index.js Imports WHIPControl; renders "WebRTC ingest (WHIP)" section before WHEP in the Processing & Control tab; monkey-patches props.restreamer._upsertProcess in handleDone to inject whip_ingest.enabled into the process config before it reaches the Core API (the SDK's UpsertIngest does not forward this field natively)

Infrastructure

Commit File Change
353fa0f deploy/truenas/core/seed-data.sh Always-overwrite index.html, asset-manifest.json, and static/ on container start so a redeployed image immediately serves the new UI bundle without manual intervention

Architecture notes

  • WHIP activation path: UI checkbox → control.whip_ingest.enable → monkey-patch injects whip_ingest: {enabled: true} → Core API PUT /api/v3/process/{id}http/api/process.go Marshal()app.Config.WHIPIngest.Enabled = trueonWHIPProcessStart hook (in app/webrtc/whip_lifecycle.go) creates an IngestPeer for the channel → browser/OBS pushes via POST /api/v3/whip/{id}
  • enable vs enabled: UI state uses enable (no trailing d) to match WHEP.js convention; the Core API JSON uses enabled. The monkey-patch performs the mapping.
  • SDK gap: The datarhei Restreamer SDK's UpsertIngest builds the ffmpeg process config from control.hls, control.rtmp, control.srt, and control.process — but explicitly ignores control.webrtc and control.whip_ingest. The WHIP patch intercepts _upsertProcess (the internal method called by UpsertIngest) to add the field before the PUT reaches Core.

Verified in production

  • Binary strings confirm *api.ProcessConfigWHIPIngest and json:"whip_ingest" compiled into /core/bin/core
  • Live bundle main.117da44e.js contains whip_ingest (multiple occurrences from WHIPControl + Edit page)
  • Container running image 54c2bddbc10d (built 2026-05-09)
  • Core logs show normal startup with process lifecycle active
## WHIP Ingest — Implementation Complete ✅ All four tasks are done and running in production. --- ### What was built **Backend — Go (datarhei-dragonfork-core)** | Commit | File | Change | |--------|------|--------| | `4ac63dd` | `app/api/api.go` | Added `whiphandler *appwebrtc.WHIPHandler` field; switched to `MergedHooks()` so WHIP lifecycle hooks register alongside WHEP; wired `NewWHIPHandler` into server config; added cleanup | | `4d94c88` | `http/api/process.go` | Added `ProcessConfigWHIPIngest` struct; added `WHIPIngest` field to `ProcessConfig`; wired `Marshal()` and `Unmarshal()` so the API accepts and returns `whip_ingest.{enabled,video_pt,audio_pt}` | **Frontend — wilddragon-restreamer-ui overlay** | Commit | File | Change | |--------|------|--------| | `ab8432d` | `overlay/src/misc/controls/WHIP.js` | New control component — enable checkbox bound to `control.whip_ingest.enable`, mirrors WHEP.js pattern | | `0f5163e` | `overlay/src/views/Edit/index.js` | Imports WHIPControl; renders "WebRTC ingest (WHIP)" section before WHEP in the Processing & Control tab; monkey-patches `props.restreamer._upsertProcess` in `handleDone` to inject `whip_ingest.enabled` into the process config before it reaches the Core API (the SDK's `UpsertIngest` does not forward this field natively) | **Infrastructure** | Commit | File | Change | |--------|------|--------| | `353fa0f` | `deploy/truenas/core/seed-data.sh` | Always-overwrite `index.html`, `asset-manifest.json`, and `static/` on container start so a redeployed image immediately serves the new UI bundle without manual intervention | --- ### Architecture notes - **WHIP activation path**: UI checkbox → `control.whip_ingest.enable` → monkey-patch injects `whip_ingest: {enabled: true}` → Core API `PUT /api/v3/process/{id}` → `http/api/process.go Marshal()` → `app.Config.WHIPIngest.Enabled = true` → `onWHIPProcessStart` hook (in `app/webrtc/whip_lifecycle.go`) creates an `IngestPeer` for the channel → browser/OBS pushes via `POST /api/v3/whip/{id}` - **`enable` vs `enabled`**: UI state uses `enable` (no trailing d) to match WHEP.js convention; the Core API JSON uses `enabled`. The monkey-patch performs the mapping. - **SDK gap**: The datarhei Restreamer SDK's `UpsertIngest` builds the ffmpeg process config from `control.hls`, `control.rtmp`, `control.srt`, and `control.process` — but explicitly ignores `control.webrtc` and `control.whip_ingest`. The WHIP patch intercepts `_upsertProcess` (the internal method called by `UpsertIngest`) to add the field before the PUT reaches Core. --- ### Verified in production - Binary strings confirm `*api.ProcessConfigWHIPIngest` and `json:"whip_ingest"` compiled into `/core/bin/core` - Live bundle `main.117da44e.js` contains `whip_ingest` (multiple occurrences from WHIPControl + Edit page) - Container running image `54c2bddbc10d` (built 2026-05-09) - Core logs show normal startup with process lifecycle active
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#16
No description provided.