Files
MultiRoombaRover/pi/bin/audio-only-publisher.sh
T
2026-06-26 13:47:23 -04:00

88 lines
2.4 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
set +H
ENV_FILE="${VIDEO_ENV_FILE:-/var/lib/roverd/video.env}"
if [[ ! -f "$ENV_FILE" ]]; then
echo "Environment file ${ENV_FILE} missing; cannot publish audio" >&2
exit 1
fi
# shellcheck disable=SC1090
source "$ENV_FILE"
AUDIO_ENABLE="${AUDIO_ENABLE:-0}"
if [[ "${AUDIO_ENABLE}" -ne 1 ]]; then
echo "Audio capture disabled; skipping audio-only publisher" >&2
exit 0
fi
: "${AUDIO_PUBLISH_URL:?AUDIO_PUBLISH_URL not set in ${ENV_FILE}}"
AUDIO_DEVICE="${AUDIO_DEVICE:-hw:0,0}"
if [[ -n "${FFMPEG_BIN:-}" ]]; then
FFMPEG_BIN_PATH="$FFMPEG_BIN"
elif command -v ffmpeg >/dev/null 2>&1; then
FFMPEG_BIN_PATH="$(command -v ffmpeg)"
else
echo "ffmpeg not found; install it via apt install ffmpeg." >&2
exit 1
fi
run_pipeline() {
local ffmpeg_args=(
-hide_banner
-loglevel warning
-fflags nobuffer
-rtbufsize 0
-thread_queue_size 4096
# Match the raw ALSA stream exactly so ffmpeg does not guess the pipe
# format and so the published audio stays full-band stereo before the
# Opus encoder sees it.
-f s32le
-ar 48000
-ac 2
-i pipe:0
# Keep the known-required microphone boost, but remove the old
# resample/downmix filter. That old filter threw away stereo and
# limited the stream to narrow 16 kHz mono before encoding.
-af "volume=25dB"
# Opus supports up to 510 kbps. Using that ceiling keeps the stream at
# the highest practical quality browsers and MediaMTX can carry without
# trying to push raw PCM through the live path.
-c:a libopus
-b:a 510000
-ar:a 48000
-ac:a 2
# Use the audio profile for quality. Latency is still controlled by the
# 20 ms Opus frame size and the low-buffering capture/publish options
# around the encoder.
-application audio
-frame_duration 20
-compression_level 0
-f mpegts
"${AUDIO_PUBLISH_URL}"
)
# The Google Voice HAT microphone path is intentionally fixed instead of
# configurable. The previous env-driven sample rate/channel knobs made it
# easy for the rover config and the actual ffmpeg pipeline to drift apart,
# while the hardware path we install is always 48 kHz stereo capture.
arecord -D "${AUDIO_DEVICE}" -f S32_LE -c 2 -r 48000 -B 65536 -F 2048 -q -t raw \
| "${FFMPEG_BIN_PATH}" "${ffmpeg_args[@]}"
}
trap 'kill 0 2>/dev/null' EXIT INT TERM
while true; do
if run_pipeline; then
exit 0
fi
echo "Audio-only publisher exited arecord=${PIPESTATUS[0]} ffmpeg=${PIPESTATUS[1]}, restarting in 2s..." >&2
sleep 2
done