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.
31 lines
1.1 KiB
Go
31 lines
1.1 KiB
Go
// Package webrtc is the datarhei Core subsystem that turns WebRTC into
|
|
// a first-class output alongside RTMP, SRT, and HLS. It owns the WHEP
|
|
// HTTP handler, wires FFmpeg's RTP output into per-process Pion
|
|
// Sources, and tracks active peer connections.
|
|
//
|
|
// See docs/design/2026-04-17-datarhei-dragon-fork-m2-webrtc-core-integration.md
|
|
// for the full design.
|
|
package webrtc
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
// Alloc binds :0 on loopback UDPv4, records the port the kernel assigned,
|
|
// closes the socket, and returns the port number.
|
|
//
|
|
// The caller is expected to re-bind that exact port via
|
|
// core/webrtc.NewSourceOn immediately. There is a microsecond-sized race
|
|
// window where another process on the host could grab the port; if that
|
|
// happens, the caller's rebind will fail and the error should be
|
|
// propagated. In practice this is rare enough that a retry loop would be
|
|
// unnecessary churn.
|
|
func Alloc() (int, error) {
|
|
c, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
|
|
if err != nil {
|
|
return 0, fmt.Errorf("webrtc: portalloc: %w", err)
|
|
}
|
|
defer c.Close()
|
|
return c.LocalAddr().(*net.UDPAddr).Port, nil
|
|
}
|