datarhei-dragonfork-core/app/webrtc/ffmpeg_args.go
Zac Gaetano 16ae17d2a1 feat(app/webrtc): port allocator + FFmpeg arg builder
Adds Alloc(), the ephemeral loopback UDP port grabber the subsystem
uses to pick the RTP port it will hand to FFmpeg and then re-bind with
core/webrtc.NewSourceOn. Covered by a 100x rebind test.

Adds BuildArgs(), which emits the -f rtp output fragments (video on
the passed port, audio on port+1) with copy codecs by default and an
H.264 baseline / libopus re-encode leg when ForceTranscode is set.
Covered by three unit tests.
2026-04-17 09:52:09 -04:00

52 lines
1.5 KiB
Go

package webrtc
import (
"fmt"
appcfg "github.com/datarhei/core/v16/restream/app"
)
// BuildArgs emits the FFmpeg output-leg args for the WebRTC side of a
// process. It produces two separate "outputs" — one for video on
// videoPort, one for audio on videoPort+1. Each output ends with its
// UDP address so the slice is structured for consumption by
// restream.AppendOutput after splitting on the track boundary.
//
// Copy vs. re-encode: if ForceTranscode is false, we assume the upstream
// source is already H.264 + Opus and pass them through (copy). When the
// source doesn't match, FFmpeg will fail at runtime and the process will
// restart — the user can flip ForceTranscode on to get a baseline-profile
// H.264 + Opus re-encode.
func BuildArgs(cfg appcfg.ConfigWebRTC, videoPort int) []string {
vcopy := []string{"-c:v", "copy"}
acopy := []string{"-c:a", "copy"}
if cfg.ForceTranscode {
vcopy = []string{
"-c:v", "libx264",
"-preset", "veryfast",
"-profile:v", "baseline",
"-pix_fmt", "yuv420p",
"-tune", "zerolatency",
"-g", "60",
}
acopy = []string{"-c:a", "libopus", "-b:a", "96k"}
}
args := []string{"-map", "0:v:0"}
args = append(args, vcopy...)
args = append(args,
"-payload_type", fmt.Sprint(cfg.VideoPT),
"-f", "rtp",
fmt.Sprintf("udp://127.0.0.1:%d?pkt_size=1316", videoPort),
)
args = append(args, "-map", "0:a:0")
args = append(args, acopy...)
args = append(args,
"-payload_type", fmt.Sprint(cfg.AudioPT),
"-f", "rtp",
fmt.Sprintf("udp://127.0.0.1:%d?pkt_size=1316", videoPort+1),
)
return args
}