feat(config): add ConfigWHIPIngest to per-process config (issue #16)
Some checks failed
ci / race tests (push) Blocked by required conditions
ci / WebRTC smoke (5-viewer fanout) (push) Blocked by required conditions
ci / WebRTC latency p95 gate (push) Blocked by required conditions
ci / vet + build (push) Has been cancelled

Adds the ConfigWHIPIngest struct alongside the existing ConfigWebRTC.
When Enabled=true the app/webrtc subsystem (next commit) will prepend
RTP UDP input legs to the FFmpeg command, binding on loopback ports
that WHIP publisher peers write received WebRTC tracks to.
This commit is contained in:
Zac Gaetano 2026-05-09 16:18:43 -04:00
parent 890b09a33c
commit 5f9ba6f764

View file

@ -43,6 +43,28 @@ type ConfigWebRTC struct {
// provided for symmetry with other Clone methods and future-proofing).
func (w ConfigWebRTC) Clone() ConfigWebRTC { return w }
// ConfigWHIPIngest carries per-process WHIP ingest settings.
//
// When Enabled is true the app/webrtc subsystem will, at process start,
// allocate two adjacent loopback UDP ports and prepend them as RTP input
// legs to the FFmpeg command. A browser or OBS publisher then connects
// to POST /api/v3/whip/{id} and the received WebRTC tracks are forwarded
// to those ports, giving FFmpeg its video+audio input via WebRTC.
//
// Flow (symmetric to WHEP egress):
// browser → WHIP → Pion → UDP → FFmpeg input → FFmpeg outputs (RTMP/SRT/HLS…)
//
// VideoPT / AudioPT are the RTP payload types Pion will stamp on forwarded
// packets. Defaults match the WHEP egress defaults (102/111).
type ConfigWHIPIngest struct {
Enabled bool `json:"enabled"`
VideoPT uint8 `json:"video_pt"`
AudioPT uint8 `json:"audio_pt"`
}
// Clone returns a value copy of the WHIP ingest config.
func (w ConfigWHIPIngest) Clone() ConfigWHIPIngest { return w }
func (io ConfigIO) Clone() ConfigIO {
clone := ConfigIO{
ID: io.ID,
@ -59,20 +81,21 @@ func (io ConfigIO) Clone() ConfigIO {
}
type Config struct {
ID string `json:"id"`
Reference string `json:"reference"`
FFVersion string `json:"ffversion"`
Input []ConfigIO `json:"input"`
Output []ConfigIO `json:"output"`
Options []string `json:"options"`
Reconnect bool `json:"reconnect"`
ReconnectDelay uint64 `json:"reconnect_delay_seconds"` // seconds
Autostart bool `json:"autostart"`
StaleTimeout uint64 `json:"stale_timeout_seconds"` // seconds
LimitCPU float64 `json:"limit_cpu_usage"` // percent
LimitMemory uint64 `json:"limit_memory_bytes"` // bytes
LimitWaitFor uint64 `json:"limit_waitfor_seconds"` // seconds
WebRTC ConfigWebRTC `json:"webrtc"`
ID string `json:"id"`
Reference string `json:"reference"`
FFVersion string `json:"ffversion"`
Input []ConfigIO `json:"input"`
Output []ConfigIO `json:"output"`
Options []string `json:"options"`
Reconnect bool `json:"reconnect"`
ReconnectDelay uint64 `json:"reconnect_delay_seconds"` // seconds
Autostart bool `json:"autostart"`
StaleTimeout uint64 `json:"stale_timeout_seconds"` // seconds
LimitCPU float64 `json:"limit_cpu_usage"` // percent
LimitMemory uint64 `json:"limit_memory_bytes"` // bytes
LimitWaitFor uint64 `json:"limit_waitfor_seconds"` // seconds
WebRTC ConfigWebRTC `json:"webrtc"`
WHIPIngest ConfigWHIPIngest `json:"whip_ingest,omitempty"`
}
func (config *Config) Clone() *Config {
@ -88,6 +111,7 @@ func (config *Config) Clone() *Config {
LimitMemory: config.LimitMemory,
LimitWaitFor: config.LimitWaitFor,
WebRTC: config.WebRTC.Clone(),
WHIPIngest: config.WHIPIngest.Clone(),
}
clone.Input = make([]ConfigIO, len(config.Input))