Skip to content

Instantly share code, notes, and snippets.

@dbaldwin
Last active March 17, 2026 19:21
Show Gist options
  • Select an option

  • Save dbaldwin/5ddc6867737dcb32f2c603244b904f38 to your computer and use it in GitHub Desktop.

Select an option

Save dbaldwin/5ddc6867737dcb32f2c603244b904f38 to your computer and use it in GitHub Desktop.
Setup RTSP streaming on DEXI (Pi camera → QGroundControl via mediamtx)
#!/bin/bash
# Revert from RTSP streaming back to ROS2 camera (dexi.service)
#
# Usage:
# bash revert_to_ros2.sh
set -e
echo "==> Stopping mediamtx..."
sudo systemctl stop mediamtx 2>/dev/null || sudo pkill mediamtx 2>/dev/null || true
sudo pkill -f 'ffmpeg.*rtsp' 2>/dev/null || true
echo "==> Disabling mediamtx service..."
sudo systemctl disable mediamtx 2>/dev/null || true
echo "==> Starting dexi service..."
sudo systemctl start dexi
sleep 3
if systemctl is-active --quiet dexi; then
echo ""
echo "==> Reverted to ROS2 camera successfully!"
echo " dexi.service is running"
echo ""
echo " To switch back to RTSP later:"
echo " sudo systemctl stop dexi"
echo " sudo systemctl enable mediamtx"
echo " sudo systemctl start mediamtx"
else
echo "==> ERROR: dexi.service failed to start"
journalctl -u dexi --no-pager -n 20
exit 1
fi
#!/bin/bash
# Setup RTSP streaming on Dexi drone (Raspberry Pi with CSI or USB camera)
# Streams camera directly via mediamtx → QGroundControl
# QGC connects to: rtsp://<pi-ip>:8554/cam
#
# Supports:
# - CSI cameras (IMX219, etc.) via mediamtx native rpiCamera (hardware H264, ~8% CPU)
# - USB cameras (Arducam, etc.) via ffmpeg (software H264, higher CPU)
#
# Prerequisites:
# - No other process using the camera (stop dexi first: sudo systemctl stop dexi)
#
# Usage:
# bash setup_rtsp.sh
set -e
MEDIAMTX_VERSION="v1.16.3"
INSTALL_DIR="/usr/local/bin"
CONFIG_DIR="/etc/mediamtx"
# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
aarch64) TARBALL="mediamtx_${MEDIAMTX_VERSION}_linux_arm64.tar.gz" ;;
armv7l) TARBALL="mediamtx_${MEDIAMTX_VERSION}_linux_armv7.tar.gz" ;;
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
esac
# Detect camera type
detect_camera() {
# Check for CSI camera first
if rpicam-hello --list-cameras 2>&1 | grep -q "Available cameras"; then
if rpicam-hello --list-cameras 2>&1 | grep -q "[0-9] :"; then
echo "csi"
return
fi
fi
# Check for USB camera
if v4l2-ctl --list-devices 2>&1 | grep -q "usb"; then
USB_DEV=$(v4l2-ctl --list-devices 2>&1 | grep -A1 "usb" | grep /dev/video | head -1 | tr -d '[:space:]')
if [ -n "$USB_DEV" ]; then
echo "usb:$USB_DEV"
return
fi
fi
echo "none"
}
echo "==> Detecting camera..."
CAMERA=$(detect_camera)
CAMERA_TYPE="${CAMERA%%:*}"
CAMERA_DEV="${CAMERA#*:}"
if [ "$CAMERA_TYPE" = "none" ]; then
echo "ERROR: No camera detected. Make sure dexi is stopped (sudo systemctl stop dexi) and a camera is connected."
exit 1
fi
echo " Detected: $CAMERA_TYPE camera${CAMERA_DEV:+ at $CAMERA_DEV}"
# Download mediamtx if not already installed
if [ ! -x "${INSTALL_DIR}/mediamtx" ]; then
echo "==> Downloading mediamtx ${MEDIAMTX_VERSION} for ${ARCH}..."
cd /tmp
curl -L -o mediamtx.tar.gz "https://github.com/bluenviron/mediamtx/releases/download/${MEDIAMTX_VERSION}/${TARBALL}"
tar xzf mediamtx.tar.gz mediamtx
echo "==> Installing mediamtx to ${INSTALL_DIR}..."
sudo mv mediamtx "${INSTALL_DIR}/mediamtx"
sudo chmod +x "${INSTALL_DIR}/mediamtx"
rm mediamtx.tar.gz
else
echo "==> mediamtx already installed at ${INSTALL_DIR}/mediamtx"
fi
# Create config based on camera type
echo "==> Creating config at ${CONFIG_DIR}/mediamtx.yml..."
sudo mkdir -p "$CONFIG_DIR"
if [ "$CAMERA_TYPE" = "csi" ]; then
sudo tee "${CONFIG_DIR}/mediamtx.yml" > /dev/null << 'EOF'
paths:
cam:
source: rpiCamera
rpiCameraWidth: 320
rpiCameraHeight: 240
rpiCameraFPS: 30
rpiCameraIDRPeriod: 15
rpiCameraBitrate: 1000000
EOF
EXTRA_SERVICE=""
else
sudo tee "${CONFIG_DIR}/mediamtx.yml" > /dev/null << 'EOF'
paths:
cam:
source: publisher
EOF
EXTRA_SERVICE="ExecStartPost=/bin/bash -c 'sleep 2 && ffmpeg -f v4l2 -input_format mjpeg -video_size 320x240 -framerate 30 -i ${CAMERA_DEV} -c:v libx264 -pix_fmt yuv420p -preset ultrafast -tune zerolatency -b:v 1M -g 15 -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/cam &'"
fi
# Create systemd service
echo "==> Creating systemd service..."
sudo tee /etc/systemd/system/mediamtx.service > /dev/null << EOF
[Unit]
Description=MediaMTX RTSP Server
After=network.target
[Service]
ExecStart=${INSTALL_DIR}/mediamtx ${CONFIG_DIR}/mediamtx.yml
${EXTRA_SERVICE}
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable mediamtx
sudo systemctl start mediamtx
sleep 3
# Verify
if systemctl is-active --quiet mediamtx; then
IP=$(hostname -I | awk '{print $1}')
echo ""
echo "==> RTSP streaming is running! (${CAMERA_TYPE} camera)"
echo " QGC URL: rtsp://${IP}:8554/cam"
echo ""
echo " QGC Settings: Application Settings > General > Video"
echo " Source: RTSP Video Stream"
echo " RTSP URL: rtsp://${IP}:8554/cam"
echo " Aspect Ratio: 1.333333"
echo " Low Latency Mode: checked"
echo ""
echo " To stop: sudo systemctl stop mediamtx"
echo " To start: sudo systemctl start mediamtx"
echo " Logs: journalctl -u mediamtx -f"
else
echo "==> ERROR: mediamtx failed to start"
journalctl -u mediamtx --no-pager -n 20
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment