Skip to content

Adds full WHIP and WHEP support to Moblin#227

Closed
anishmenon wants to merge 4 commits intoeerimoq:mainfrom
nexhe:feature/whip-whep
Closed

Adds full WHIP and WHEP support to Moblin#227
anishmenon wants to merge 4 commits intoeerimoq:mainfrom
nexhe:feature/whip-whep

Conversation

@anishmenon
Copy link

Summary

Adds full WHIP and WHEP support to Moblin, enabling ultra-low-latency WebRTC streaming in all three directions:

  • WHIP Publishing (Stream out): Stream from Moblin to any WHIP-compatible endpoint (e.g., Cloudflare, Dolby.io, self-hosted servers) — just like RTMP/SRT but with sub-second latency. Available as a stream protocol option under Settings → Streams.
  • WHIP Server (Ingest in): Run a local WHIP server so external apps like OBS or FFmpeg can publish streams into Moblin over the local network. Ingested streams appear as selectable camera sources in scenes. Available under Settings → Ingests.
  • WHEP Client (Playback): Subscribe to remote WebRTC streams via WHEP and use them as camera sources within Moblin. Available under Settings → Ingests.

Motivation

Addresses community feature requests for ultra-low-latency streaming using WebRTC. WHIP/WHEP are the standard HTTP-based signaling protocols for WebRTC, supported by OBS, FFmpeg 8+, Cloudflare, and many other platforms.

Changes

Commit 1: Vendor HaishinKit.swift — Adds HaishinKit.swift (with RTCHaishinKit) as a local Swift package for WebRTC support. Includes patches for H.264 STAP-A decoding, recvonly track lifecycle, and a compressed video callback hook.

Commit 2: WHIP/WHEP feature (35 files, ~2300 lines) — The actual feature implementation:

  • WHIP server with full ICE negotiation, trickle ICE (PATCH), and session teardown (DELETE)
  • WHEP client for subscribing to external WebRTC sources
  • WHIP publishing client using RTCHaishinKit's session builder
  • RTMP-style video decode pipeline (PTS retiming before decode) for smooth ingest playback
  • VideoDecoder session auto-recovery on persistent decode errors
  • Settings UI for WHIP server streams, WHEP client streams, and WHIP publishing
  • HttpServer extended with routing, response headers, and method dispatch
  • WHIP/WHEP streams as selectable camera sources in scene and widget configuration
  • Configurable buffer latency with 500ms cap for WebRTC ingest

Test plan

  • Publish from Moblin via WHIP to a WHIP-compatible server
  • Stream from OBS via WHIP to Moblin's WHIP server and verify video/audio in a scene
  • Subscribe to a remote WebRTC source via WHEP
  • Verify trickle ICE with PATCH
  • Verify session teardown (DELETE) and reconnection
  • Verify WHIP/WHEP camera sources in scene configuration

anishmenon and others added 3 commits February 8, 2026 17:17
Vendor HaishinKit.swift (with RTCHaishinKit) as a local Swift package
to enable WHIP/WHEP WebRTC support. Includes patches for:
- H.264 STAP-A (NAL type 24) decoding in RTPH264Packetizer
- Recvonly track lifecycle management in RTCPeerConnection
- Compressed video callback hook (onCompressedVideo) for direct
  video track access bypassing IncomingStream

Co-authored-by: Cursor <cursoragent@cursor.com>
Add WHIP publishing as a stream protocol for ultra-low-latency
streaming to WHIP-compatible endpoints. Add a built-in WHIP server
for receiving WebRTC streams from OBS/FFmpeg as camera sources.
Add a WHEP client for subscribing to remote WebRTC streams.

- WHIP publishing alongside RTMP, SRT, RIST in stream settings
- WHIP server with ICE negotiation, trickle ICE, session teardown
- WHEP client with configurable URL and latency per stream
- RTMP-style video decode pipeline for smooth ingest playback
- VideoDecoder session recovery on persistent decode errors
- WHIP/WHEP streams as selectable camera sources in scenes
- Settings UI for WHIP server, WHEP client, and WHIP publishing
- HttpServer extended with routing, response headers, and CORS

Co-authored-by: Cursor <cursoragent@cursor.com>
@eerimoq
Copy link
Owner

eerimoq commented Feb 9, 2026

Nice try, but way too messy to even consider reviewing, sorry.

- Define ChatPlatformStatus struct and add chatPlatformStatuses property
  to StatusTopLeft for per-platform chat connection status display
- Add SettingsWidgetBrowserMode enum (periodicAudioAndVideo,
  audioAndVideoOnly, audioOnly) replacing the old audioAndVideoOnly bool
  on SettingsWidgetBrowser, with backward-compatible decoding
- Fix ModelScene scoreboard update to use getModularScoreboardConfig()
  instead of non-existent getCurrentConfig()
- Update bundle identifiers from com.eerimoq.Mobs to io.webmo.mocam
- Add WHIP/WHEP localization strings
@eerimoq
Copy link
Owner

eerimoq commented Feb 11, 2026

Closing in favour of #233

@eerimoq eerimoq closed this Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants