Skip to content Link Search Menu Expand Document
ModalAI DOCS
Store

How to Stream Video with RTSP on VOXL

Table of contents

  1. Overview
  2. Reusable GStreamer Source
  3. General Use as a Service
  4. Configuration File
  5. Two Primary Modes
  6. Running Multiple Instances
  7. Command Line Reference
  8. Troubleshooting

Overview

voxl-streamer is a background service that subscribes to MPA image streams, compresses them if necessary, and makes them available as an RTSP stream at:

rtsp://<VOXL_IP>:8900/live

The port is configurable (default 8900); the /live mount point is fixed. This is enabled by default on most systems to enable automatic streaming of video to QGroundControl by voxl-mavcam-manager — FPV SKUs are the exception, where video ships through voxl-vtx instead.

This video shows setting up a 720p encoded video stream with a VOXL 2 and IMX412: YouTube

Reusable GStreamer Source

voxl-streamer consumes camera pipes through mpasrc, a reusable GStreamer source element provided by libgstmpa.so. It handles the MPA client connection, camera metadata, timestamps, frame queue, and decimation. voxl-streamer uses this element internally and provides its configuration file, CLI, systemd service, encoding, and /live RTSP endpoint.

The same package also includes gst-rtsp-launch, a foreground RTSP server for custom GStreamer pipelines. You can use mpasrc directly with gst-launch-1.0, gst-rtsp-launch, or your own GStreamer application without running the voxl-streamer service. The plugin and launcher ship in the voxl-streamer package; deploy the full package when updating the application.

See MPA GStreamer Pipelines for setup checks, supported formats, source properties, and raw/H.264/H.265 examples. The generic launcher’s default URL is rtsp://<VOXL_IP>:8554/test; voxl-streamer’s default remains rtsp://<VOXL_IP>:8900/live.

General Use as a Service

voxl-streamer runs in the background via its systemd service (visible in voxl-inspect-services), started with no arguments — all behavior comes from the config file. Manage it with:

voxl-configure-streamer factory_enable   # reset config to defaults and enable
voxl-configure-streamer enable           # enable (starts on next reboot)
voxl-configure-streamer disable          # disable and stop

Multiple RTSP clients can watch the same stream simultaneously — the encoded media is shared. When no clients are connected, voxl-streamer disconnects from the MPA pipe entirely to save power and CPU, reconnecting when the next client shows up.

Configuration File

/etc/modalai/voxl-streamer.conf (JSON, created with defaults on first run):

FieldDefaultMeaning
input-pipehires_small_encodedMPA camera pipe to subscribe to
port8900RTSP port to serve on
bitrate1000000Bitrate for onboard encoding — raw input only (see below)
decimator1Drop frames to reduce framerate — raw input only
rotation0Rotate the video 0/90/180/270 degrees — raw input only
encoderh264Onboard encoder when input is not already encoded: h264 or h265

Two Primary Modes

Pre-encoded input (default). voxl-streamer can subscribe to pre-encoded H264 or H265 MPA pipes such as the default hires_small_encoded. This is most efficient: frames pass straight through to RTSP with no re-encode. In this mode the bitrate, rotation, and decimator fields are ignored — set bitrate and GOP in voxl-camera-server.conf instead.

Raw input. When pointed at an uncompressed pipe (RAW8, NV12, YUV, RGB — e.g. tracking or qvio_overlay), voxl-streamer builds a GStreamer pipeline that can rotate, decimate, and compress the video to the configured bitrate using the platform’s hardware encoder. This works well but is less efficient than pre-encoded input.

The original VOXL (apq8096) supports H264 onboard encoding only — encoder: h265 errors out there. VOXL 2 supports both.

Running Multiple Instances

Each voxl-streamer process serves one stream. To stream a second camera alongside the background service, launch another instance with --standalone (so it doesn’t kill the service’s process) and a unique --port:

voxl-streamer --standalone --port 8901 -i tracking

That second stream is then at rtsp://<VOXL_IP>:8901/live.

Running voxl-streamer by hand without --standalone kills the running background service instance — that’s by design, so a manual run can take over cleanly.

Command Line Reference

-b --bitrate    <#>     | Override bitrate specified in the config file
-c --config             | Load config file only and quit (used for scripted setup)
-d --decimator  <#>     | Override the decimator specified in the config file
-h --help               | Print this help message
-i --input-pipe <name>  | Override the input pipe specified in the config file
-e --encoder <type>     | Choose video encoder h264 or h265 (if video is not already encoded)
-p --port       <#>     | Override the RTSP port number specified in the config file
-s --standalone         | Use this to launch a new instance alongside the default service
-v --verbosity  <#>     | Log verbosity level (Default 2)

CLI flags override the config file. Tab completion is installed — -i completes live camera pipes.

Troubleshooting

For general service debugging — logs, restarts, running in the foreground — see Debugging Services.

  • Stream won’t open: confirm the service is running (voxl-inspect-services) and the configured input-pipe exists (voxl-list-pipes). The startup log prints the stream URL.
  • Choppy or stalling video: voxl-streamer drops frames rather than buffering under load; if the source pipe backs up it is flushed. Reduce resolution/bitrate at the source, or lower the framerate with decimator (raw input).
  • MPA frame size does not match its format: the raw frame byte count does not match the expected dimensions and pixel format; re-check the camera configuration and publisher metadata.
  • Couldn't make mpa_source: confirm the package’s libgstmpa.so is installed and gst-inspect-1.0 mpasrc succeeds. See plugin troubleshooting.
  • Rotation/bitrate/decimator “not working”: those only apply to raw input — with a pre-encoded pipe, adjust voxl-camera-server.conf.
  • mpasrc handles automatic reconnection after temporary camera server disconnects. If the camera format or resolution changes, restart voxl-streamer so it can configure the downstream pipeline for the new input.

For a deeper latency-focused setup, see Low Latency Video Streaming.