GStreamer Plugin
The Moq GStreamer plugin provides moqsrc and moqsink elements for integrating Moq into GStreamer pipelines. This enables efficient media processing and streaming with full control over encoding, decoding, and transformations.
This plugin is currently under development but works well for most use cases. Contributions are welcome!
Overview
The GStreamer plugin provides two main elements:
moqsink : Publish media to Moq relays
moqsrc : Subscribe to Moq broadcasts
Repository
The plugin is maintained in a separate repository:
Moq GStreamer Plugin View source code, installation instructions, and examples
Installation
Ensure GStreamer development libraries are installed:
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo dnf install gstreamer1-devel gstreamer1-plugins-base-devel
brew install gstreamer gst-plugins-base
git clone https://github.com/moq-dev/gstreamer
cd gstreamer
Copy the built plugin to your GStreamer plugins directory:
cp target/release/libhang_gst.so ~/.local/share/gstreamer-1.0/plugins/
On macOS, the extension is .dylib instead of .so.
Check that GStreamer recognizes the plugin:
gst-inspect-1.0 moqsink
gst-inspect-1.0 moqsrc
Publishing with moqsink
Basic Publishing Pipeline
Publish a test video pattern:
gst-launch-1.0 videotestsrc ! x264enc ! \
isofmp4mux name=mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://cdn.moq.dev/anon broadcast=test
Publish from Webcam
Stream from a video device:
Linux (v4l2)
macOS (avfoundation)
gst-launch-1.0 v4l2src device=/dev/video0 ! \
videoconvert ! x264enc tune=zerolatency ! \
isofmp4mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://relay.example.com/anon broadcast=webcam
Publish with Audio
Include audio in your stream:
gst-launch-1.0 \
videotestsrc ! videoconvert ! x264enc ! mux.video \
audiotestsrc ! audioconvert ! avenc_aac ! mux.audio \
isofmp4mux name=mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://relay.example.com/anon broadcast=test
Publish a File
Stream a video file:
gst-launch-1.0 filesrc location=video.mp4 ! \
qtdemux ! h264parse ! mux.video \
isofmp4mux name=mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://relay.example.com/anon broadcast=video
Subscribing with moqsrc
Basic Playback Pipeline
Subscribe and play a Moq broadcast:
gst-launch-1.0 moqsrc url=https://cdn.moq.dev/anon broadcast=test ! \
decodebin ! autovideosink
Save to File
Record a Moq broadcast to a file:
gst-launch-1.0 moqsrc url=https://relay.example.com/anon broadcast=stream ! \
filesink location=output.mp4
Transcode and Republish
Subscribe, transcode, and republish:
gst-launch-1.0 \
moqsrc url=https://relay.example.com/anon broadcast=source ! \
decodebin ! videoconvert ! \
x264enc bitrate= 1000 ! \
isofmp4mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://relay.example.com/anon broadcast=transcoded
moqsink Properties
Configure the moqsink element:
Property Type Default Description urlstring required Relay server URL broadcaststring required Broadcast name jwtstring - Authentication token
Example with Properties
gst-launch-1.0 videotestsrc ! x264enc ! \
isofmp4mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url="https://relay.example.com/anon" \
broadcast="my-stream" \
jwt="<token>"
moqsrc Properties
Configure the moqsrc element:
Property Type Default Description urlstring required Relay server URL broadcaststring required Broadcast name jwtstring - Authentication token
Advanced Pipelines
Multi-Bitrate Publishing
Publish multiple quality levels:
gst-launch-1.0 videotestsrc ! tee name=t \
t. ! queue ! videoscale ! video/x-raw,width=1920,height= 1080 ! \
x264enc bitrate= 5000 ! isofmp4mux ! \
moqsink url=https://relay.example.com/anon broadcast=high \
t. ! queue ! videoscale ! video/x-raw,width=1280,height= 720 ! \
x264enc bitrate= 2500 ! isofmp4mux ! \
moqsink url=https://relay.example.com/anon broadcast=medium
Screen Capture
Capture and stream your screen:
gst-launch-1.0 ximagesrc ! \
videoconvert ! x264enc tune=zerolatency ! \
isofmp4mux chunk-duration= 1 fragment-duration= 1 ! \
moqsink url=https://relay.example.com/anon broadcast=screen
Low Latency Configuration
Optimize for minimal latency:
gst-launch-1.0 videotestsrc ! \
x264enc tune=zerolatency bitrate= 2000 \
key-int-max= 30 bframes= 0 \
byte-stream= true threads= 0 ! \
isofmp4mux chunk-duration= 1 fragment-duration= 1 \
streamable= true fragment-mode=first-moov-then-finalise ! \
moqsink url=https://relay.example.com/anon broadcast=lowlatency
Key parameters for low latency:
tune=zerolatency: Disables lookahead
key-int-max=30: Frequent keyframes (every 1 second at 30fps)
bframes=0: No B-frames
chunk-duration=1: 1-second fragments
Debugging
Enable Debug Output
Set GStreamer debug level:
GST_DEBUG = moqsink:5,moqsrc:5 gst-launch-1.0 ...
Inspect Pipeline
Visualize your pipeline:
GST_DEBUG_DUMP_DOT_DIR = . gst-launch-1.0 ...
dot -Tpng pipeline.dot -o pipeline.png
More Examples
Check the repository’s justfile for additional examples:
Troubleshooting
Plugin Not Found
Verify plugin is in GStreamer plugins directory
Run gst-inspect-1.0 moqsink to check installation
Set GST_PLUGIN_PATH if using custom location
Connection Errors
Check relay URL is accessible
Verify firewall allows UDP traffic
Ensure JWT token is valid if using authentication
Pipeline Errors
Verify all elements are installed (gst-inspect-1.0 <element>)
Check element capabilities match (use gst-inspect-1.0)
Enable debug output to identify bottlenecks
Next Steps
Deploy a Relay Set up your own relay server
FFmpeg Integration Alternative command-line publishing
Web Playback Watch streams in the browser
OBS Plugin Stream using OBS Studio