diff --git a/restream/app/process.go b/restream/app/process.go index 8381e8d..a840b2a 100644 --- a/restream/app/process.go +++ b/restream/app/process.go @@ -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))