video publisher more options

This commit is contained in:
legop3
2026-07-01 00:03:55 -04:00
parent 282cb3e135
commit 6ad7701b8f
6 changed files with 35 additions and 11 deletions
BIN
View File
Binary file not shown.
+12
View File
@@ -58,6 +58,7 @@ load_env_file
: "${ROVERD_VIDEO_ENABLE:?ROVERD_VIDEO_ENABLE not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_PUBLISH_URL:?ROVERD_VIDEO_PUBLISH_URL not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_DEVICE:?ROVERD_VIDEO_DEVICE not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_INPUT_FORMAT:?ROVERD_VIDEO_INPUT_FORMAT not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_WIDTH:?ROVERD_VIDEO_WIDTH not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_HEIGHT:?ROVERD_VIDEO_HEIGHT not set in ${ENV_FILE}}"
: "${ROVERD_VIDEO_FPS:?ROVERD_VIDEO_FPS not set in ${ENV_FILE}}"
@@ -74,6 +75,16 @@ if [[ -z "${ROVERD_VIDEO_DEVICE}" ]]; then
exit 1
fi
INPUT_FORMAT_ARGS=()
if [[ -n "${ROVERD_VIDEO_INPUT_FORMAT}" ]]; then
# Many laptop webcams expose both compressed MJPEG and raw YUYV modes. The
# wrong negotiated format can still produce a decodable stream, but the
# picture appears as green/noisy mush because ffmpeg is interpreting the
# frame bytes with the wrong pixel format. Passing input_format pins V4L2 to
# the camera mode selected in roverd.yaml.
INPUT_FORMAT_ARGS=(-input_format "${ROVERD_VIDEO_INPUT_FORMAT}")
fi
if [[ -n "${FFMPEG_BIN:-}" ]]; then
FFMPEG_BIN_PATH="$FFMPEG_BIN"
elif command -v ffmpeg >/dev/null 2>&1; then
@@ -99,6 +110,7 @@ run_pipeline() {
-flags low_delay \
-thread_queue_size 4096 \
-f v4l2 \
"${INPUT_FORMAT_ARGS[@]}" \
-framerate "${ROVERD_VIDEO_FPS}" \
-video_size "${ROVERD_VIDEO_WIDTH}x${ROVERD_VIDEO_HEIGHT}" \
-i "${ROVERD_VIDEO_DEVICE}" \
+2
View File
@@ -424,6 +424,7 @@ ROVERD_VIDEO_ENABLE=1
ROVERD_VIDEO_PUBLISHER=pi-libcamera
ROVERD_VIDEO_PUBLISH_URL=srt://192.168.0.86:9000?streamid=#!::r=CHANGE_ME,m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316
ROVERD_VIDEO_DEVICE=
ROVERD_VIDEO_INPUT_FORMAT=
ROVERD_VIDEO_WIDTH=640
ROVERD_VIDEO_HEIGHT=480
ROVERD_VIDEO_FPS=30
@@ -450,6 +451,7 @@ ROVERD_VIDEO_ENABLE=1
ROVERD_VIDEO_PUBLISHER=debian-laptop-v4l2
ROVERD_VIDEO_PUBLISH_URL=srt://192.168.0.86:9000?streamid=#!::r=CHANGE_ME,m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316
ROVERD_VIDEO_DEVICE=/dev/video0
ROVERD_VIDEO_INPUT_FORMAT=mjpeg
ROVERD_VIDEO_WIDTH=640
ROVERD_VIDEO_HEIGHT=480
ROVERD_VIDEO_FPS=30
+16 -11
View File
@@ -93,17 +93,18 @@ type VideoMediaConfig struct {
// Publisher selects the installed publisher script/pipeline family. The
// first pass uses pi-libcamera for current rovers; laptop-v4l2 can be added
// without changing the server-facing media shape again.
Enabled bool `yaml:"enabled" json:"enabled"`
Service string `yaml:"service" json:"service,omitempty"`
Publisher string `yaml:"publisher" json:"publisher,omitempty"`
PublishURL string `yaml:"publishUrl" json:"publishUrl,omitempty"`
Device string `yaml:"device" json:"device,omitempty"`
Width int `yaml:"width" json:"-"`
Height int `yaml:"height" json:"-"`
FPS int `yaml:"fps" json:"-"`
Bitrate int `yaml:"bitrate" json:"-"`
Inverted bool `yaml:"inverted" json:"-"`
SensorMode string `yaml:"sensorMode" json:"-"`
Enabled bool `yaml:"enabled" json:"enabled"`
Service string `yaml:"service" json:"service,omitempty"`
Publisher string `yaml:"publisher" json:"publisher,omitempty"`
PublishURL string `yaml:"publishUrl" json:"publishUrl,omitempty"`
Device string `yaml:"device" json:"device,omitempty"`
InputFormat string `yaml:"inputFormat" json:"-"`
Width int `yaml:"width" json:"-"`
Height int `yaml:"height" json:"-"`
FPS int `yaml:"fps" json:"-"`
Bitrate int `yaml:"bitrate" json:"-"`
Inverted bool `yaml:"inverted" json:"-"`
SensorMode string `yaml:"sensorMode" json:"-"`
}
type AudioCaptureConfig struct {
@@ -450,6 +451,10 @@ func validateVideoMediaConfig(cfg *VideoMediaConfig, serverURL string, roverName
if cfg.Publisher == "" {
cfg.Publisher = "pi-libcamera"
}
// V4L2 input formats are consumed by ffmpeg as lowercase names such as
// mjpeg or yuyv422. Normalizing here keeps the publisher script simple and
// makes hand-edited Debian laptop configs less sensitive to capitalization.
cfg.InputFormat = strings.ToLower(strings.TrimSpace(cfg.InputFormat))
if cfg.Width <= 0 {
cfg.Width = 640
}
+1
View File
@@ -36,6 +36,7 @@ func UpdatePublisherEnv(media MediaConfig) error {
fmt.Fprintf(&buf, "ROVERD_VIDEO_PUBLISHER=%s\n", media.Video.Publisher)
fmt.Fprintf(&buf, "ROVERD_VIDEO_PUBLISH_URL=%s\n", media.Video.PublishURL)
fmt.Fprintf(&buf, "ROVERD_VIDEO_DEVICE=%s\n", media.Video.Device)
fmt.Fprintf(&buf, "ROVERD_VIDEO_INPUT_FORMAT=%s\n", media.Video.InputFormat)
fmt.Fprintf(&buf, "ROVERD_VIDEO_WIDTH=%d\n", media.Video.Width)
fmt.Fprintf(&buf, "ROVERD_VIDEO_HEIGHT=%d\n", media.Video.Height)
fmt.Fprintf(&buf, "ROVERD_VIDEO_FPS=%d\n", media.Video.FPS)
@@ -31,6 +31,10 @@ media:
service: debian-laptop-video-publisher.service
publisher: debian-laptop-v4l2
device: /dev/video0
# Check supported values with:
# v4l2-ctl --device=/dev/video0 --list-formats-ext
# Common working values are mjpeg and yuyv422.
inputFormat: mjpeg
width: 640
height: 480
fps: 30