From 326ae16f6b0fa0774a677980a24c705eca90f921 Mon Sep 17 00:00:00 2001 From: legop3 Date: Fri, 14 Nov 2025 05:52:52 -0500 Subject: [PATCH] ugh --- README.md | 2 +- docs/pi-deployment.md | 18 +++++------- pi/bin/whip-publisher.sh | 62 +++++++++++++++++++++++++-------------- pi/install_roverd.sh | 63 ++++++++++++++++++++++++++++++---------- 4 files changed, 97 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 1ff6e5b5..d2f264cb 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ cd ~/MultiRoombaRover sudo ./pi/install_roverd.sh ``` -Then point each rover's `/etc/roverd.yaml` at `ws://:8080/rover`, set `name` to the rover’s ID, and (optionally) override `media.publishUrl` if your control server isn’t `192.168.0.86`. The new WHIP publisher service (`whip-publisher.service`) uses GStreamer (`gst-launch-1.0 libcamerasrc ! ... ! whipclientsink`) to encode the Pi camera to H264 and publish straight into the server’s mediaMTX instance at `http://:8889/whip/`. Install `libcamera-apps` plus `gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libcamera` on each Pi so the pipeline is available. Use the “Restart Camera” button if you enable media management so roverd can bounce the publisher service remotely. +Then point each rover's `/etc/roverd.yaml` at `ws://:8080/rover`, set `name` to the rover’s ID, and (optionally) override `media.publishUrl` if your control server isn’t `192.168.0.86`. The WHIP publisher service (`whip-publisher.service`) captures the Pi camera with `rpicam-vid`/`libcamera-vid`, pipes the raw H264 into the bundled `ffmpeg-whip`, and publishes straight into the server’s mediaMTX instance at `http://:8889/whip/`. Install `libcamera-apps` on each Pi; the installer will download the patched ffmpeg build automatically. Use the “Restart Camera” button if you enable media management so roverd can bounce the publisher service remotely. Heads-up: the BRC pulser now uses libgpiod; make sure the `roverd` service account is in the `gpio` group (or otherwise allowed to access `/dev/gpiochip*`) and set `brc.gpioChip` if your hardware exposes a different chip name. ## Fedora server deployment diff --git a/docs/pi-deployment.md b/docs/pi-deployment.md index e64bd906..dc898960 100644 --- a/docs/pi-deployment.md +++ b/docs/pi-deployment.md @@ -32,14 +32,11 @@ Run the resulting `dist/roverd-dummy` on any machine; it will connect to the ser ## Automated installation (recommended) -Make sure the Pi has GStreamer 1.22+ plus the libcamera + bad plugin sets (Bookworm ships them): +Install the Raspberry Pi camera helpers (Bookworm ships them): ```bash sudo apt update -sudo apt install libcamera-apps \ - gstreamer1.0-tools gstreamer1.0-plugins-good \ - gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \ - gstreamer1.0-libcamera +sudo apt install libcamera-apps ``` Once the binary (and repo) are on the Pi, run the helper script from the repo root: @@ -92,13 +89,14 @@ If you set `media.manage: true` in `/etc/roverd.yaml`, make sure the `roverd` se The `whip-publisher.service` unit runs `/usr/local/bin/whip-publisher`, a small shell wrapper that launches: ```bash -gst-launch-1.0 libcamerasrc ! video/x-raw,width=WIDTH,height=HEIGHT,framerate=FPS/1 \ - ! videoconvert ! x264enc tune=zerolatency bitrate=BITRATE_KB key-int-max=FPS \ - ! h264parse config-interval=1 ! whipclientsink signaller::whip-endpoint=$WHIP_URL +rpicam-vid (or libcamera-vid) --inline --timeout 0 --width=WIDTH --height=HEIGHT \ + --framerate=FPS --bitrate=BITRATE --codec h264 --profile baseline --output - \ + | ffmpeg-whip -hide_banner -loglevel warning -fflags nobuffer \ + -f h264 -i pipe:0 -c:v copy -an -f whip $WHIP_URL ``` -roverd writes `/var/lib/roverd/whip.env` on startup (and whenever you restart the service) so the publisher inherits the correct `WHIP_URL`, resolution, FPS, and bitrate. Tweak those knobs under `media.videoWidth`, `media.videoHeight`, `media.videoFps`, and `media.videoBitrate` in `/etc/roverd.yaml` if you need different camera settings. -Use `sudo systemctl status whip-publisher` to watch the pipeline logs; the unit auto-restarts whenever the network drops or GStreamer exits. +The installer downloads `ffmpeg-whip` (a WHIP-enabled FFmpeg build) and drops it at `/usr/local/bin/ffmpeg-whip`, along with its private libraries under `/usr/local/lib/ffmpeg-whip`. roverd writes `/var/lib/roverd/whip.env` on startup (and whenever you restart the service) so the publisher inherits the correct `WHIP_URL`, resolution, FPS, and bitrate. Tweak those knobs under `media.videoWidth`, `media.videoHeight`, `media.videoFps`, and `media.videoBitrate` in `/etc/roverd.yaml` if you need different camera settings. +Use `sudo systemctl status whip-publisher` to watch the pipeline logs; the unit auto-restarts whenever the network drops or FFmpeg exits. ## Server + UI diff --git a/pi/bin/whip-publisher.sh b/pi/bin/whip-publisher.sh index d84dc762..7e625dec 100644 --- a/pi/bin/whip-publisher.sh +++ b/pi/bin/whip-publisher.sh @@ -18,31 +18,51 @@ VIDEO_HEIGHT="${VIDEO_HEIGHT:-720}" VIDEO_FPS="${VIDEO_FPS:-30}" VIDEO_BITRATE="${VIDEO_BITRATE:-3000000}" -GST_BIN="${GST_BIN:-/usr/bin/gst-launch-1.0}" +if [[ -n "${LIBCAMERA_BIN:-}" ]]; then + LIBCAMERA_BIN_PATH="$LIBCAMERA_BIN" +elif command -v rpicam-vid >/dev/null 2>&1; then + LIBCAMERA_BIN_PATH="$(command -v rpicam-vid)" +elif command -v libcamera-vid >/dev/null 2>&1; then + LIBCAMERA_BIN_PATH="$(command -v libcamera-vid)" +else + echo "Neither rpicam-vid nor libcamera-vid found; install libcamera-apps." >&2 + exit 1 +fi -if [[ ! -x "$GST_BIN" ]]; then - if command -v gst-launch-1.0 >/dev/null 2>&1; then - GST_BIN="$(command -v gst-launch-1.0)" - else - echo "gst-launch-1.0 not found; install gstreamer1.0-tools and plugins." >&2 - exit 1 - fi +if [[ -n "${FFMPEG_BIN:-}" ]]; then + FFMPEG_BIN_PATH="$FFMPEG_BIN" +elif command -v ffmpeg-whip >/dev/null 2>&1; then + FFMPEG_BIN_PATH="$(command -v ffmpeg-whip)" +elif command -v ffmpeg >/dev/null 2>&1; then + FFMPEG_BIN_PATH="$(command -v ffmpeg)" +else + echo "ffmpeg not found; install it or run the installer to fetch ffmpeg-whip." >&2 + exit 1 fi run_pipeline() { - local bitrate_kbps=$((VIDEO_BITRATE / 1000)) - if [[ "$bitrate_kbps" -le 0 ]]; then - bitrate_kbps=3000 - fi - "${GST_BIN}" -e \ - libcamerasrc \ - ! "video/x-raw,width=${VIDEO_WIDTH},height=${VIDEO_HEIGHT},framerate=${VIDEO_FPS}/1" \ - ! queue \ - ! videoconvert \ - ! x264enc speed-preset=ultrafast tune=zerolatency bitrate="${bitrate_kbps}" key-int-max="${VIDEO_FPS}" byte-stream=true \ - ! "video/x-h264,profile=baseline" \ - ! h264parse config-interval=1 \ - ! whipclientsink signaller::whip-endpoint="${WHIP_URL}" + "${LIBCAMERA_BIN_PATH}" \ + --inline \ + --timeout 0 \ + --width "${VIDEO_WIDTH}" \ + --height "${VIDEO_HEIGHT}" \ + --framerate "${VIDEO_FPS}" \ + --bitrate "${VIDEO_BITRATE}" \ + --codec h264 \ + --profile baseline \ + --denoise cdn_off \ + --nopreview \ + --output - \ + | "${FFMPEG_BIN_PATH}" \ + -hide_banner \ + -loglevel warning \ + -fflags nobuffer \ + -f h264 \ + -i pipe:0 \ + -c:v copy \ + -an \ + -f whip \ + "${WHIP_URL}" } while true; do diff --git a/pi/install_roverd.sh b/pi/install_roverd.sh index 3ec42642..f6a4eddd 100755 --- a/pi/install_roverd.sh +++ b/pi/install_roverd.sh @@ -6,6 +6,10 @@ set -euo pipefail BINARY_SRC="dist/roverd" CONFIG_SRC="pi/roverd/roverd.sample.yaml" +FFMPEG_WHIP_VERSION="0.0.0" +FFMPEG_WHIP_BASE_URL="https://github.com/steel-dev/ffmpeg-whip/releases/download/v${FFMPEG_WHIP_VERSION}" +FFMPEG_WHIP_DIR="/usr/local/lib/ffmpeg-whip" +FFMPEG_WHIP_BIN="/usr/local/bin/ffmpeg-whip" usage() { cat <<'USAGE' @@ -62,6 +66,11 @@ if [[ ! -f "$CONFIG_SRC" ]]; then exit 1 fi +if ! command -v curl >/dev/null 2>&1; then + echo "curl is required by this installer" >&2 + exit 1 +fi + ensure_user() { local user="$1" local groups="${2:-}" @@ -80,24 +89,44 @@ log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" } -if ! command -v gst-launch-1.0 >/dev/null 2>&1; then - log "WARNING: gst-launch-1.0 not found; install GStreamer (sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libcamera)." -else - if command -v gst-inspect-1.0 >/dev/null 2>&1; then - if ! gst-inspect-1.0 whipclientsink >/dev/null 2>&1; then - log "WARNING: whipclientsink element missing; install gstreamer1.0-plugins-bad (1.22+)." - fi - if ! gst-inspect-1.0 libcamerasrc >/dev/null 2>&1; then - log "WARNING: libcamerasrc plugin missing; install gstreamer1.0-libcamera." - fi - if ! gst-inspect-1.0 x264enc >/dev/null 2>&1; then - log "WARNING: x264enc element missing; install gstreamer1.0-plugins-ugly." - fi - else - log "WARNING: gst-inspect-1.0 not found; unable to verify GStreamer plugins." - fi +if ! command -v rpicam-vid >/dev/null 2>&1 && ! command -v libcamera-vid >/dev/null 2>&1; then + log "WARNING: neither rpicam-vid nor libcamera-vid found in PATH; install libcamera-apps." fi +install_ffmpeg_whip() { + local arch asset tmp + arch="$(uname -m)" + case "$arch" in + aarch64) + asset="ffmpeg-whip-linux-arm64.tar.gz" + ;; + x86_64|amd64) + asset="ffmpeg-whip-linux-amd64.tar.gz" + ;; + *) + log "WARNING: ffmpeg-whip binary not available for architecture ${arch}; ensure a WHIP-capable ffmpeg is installed manually." + return + esac + tmp="$(mktemp -d)" + log "Downloading ffmpeg-whip ${FFMPEG_WHIP_VERSION} (${asset})" + if ! curl -fsSL "${FFMPEG_WHIP_BASE_URL}/${asset}" -o "${tmp}/${asset}"; then + rm -rf "$tmp" + echo "Failed to download ffmpeg-whip from ${FFMPEG_WHIP_BASE_URL}/${asset}" >&2 + exit 1 + fi + rm -rf "${FFMPEG_WHIP_DIR}" + install -d "${FFMPEG_WHIP_DIR}" + tar -xzf "${tmp}/${asset}" -C "${FFMPEG_WHIP_DIR}" --strip-components=1 + rm -rf "$tmp" + cat > "${FFMPEG_WHIP_BIN}" <<'EOF' +#!/usr/bin/env bash +export LD_LIBRARY_PATH=/usr/local/lib/ffmpeg-whip/lib:${LD_LIBRARY_PATH} +exec /usr/local/lib/ffmpeg-whip/bin/ffmpeg "$@" +EOF + chmod 0755 "${FFMPEG_WHIP_BIN}" + log "Installed ${FFMPEG_WHIP_BIN}" +} + ensure_user roverd "dialout,gpio,video,render" install -o roverd -g roverd -m 0755 "$BINARY_SRC" /usr/local/bin/roverd log "Installed roverd binary" @@ -115,6 +144,8 @@ fi install -m 0644 pi/systemd/roverd.service /etc/systemd/system/roverd.service log "Installed roverd systemd unit" +install_ffmpeg_whip + # Install WHIP publisher assets install -D -o root -g root -m 0755 pi/bin/whip-publisher.sh /usr/local/bin/whip-publisher install -m 0644 pi/systemd/whip-publisher.service /etc/systemd/system/whip-publisher.service