Rust Media Server Using GstD Rust API and GStreamer
The Rust Media Server is a Rust-based application built on top of RidgeRun's GstD Rust API. It provides a clean and reusable way to configure, launch, and manage GStreamer media pipelines from a Rust application.
The media server uses YAML configuration files to define media sources and attach optional features such as:
- Live streaming
- Recording
- Snapshot capture
Each media source can enable or customize these features independently. This makes the media server a flexible foundation for building camera applications, video-streaming systems, media-processing services, and embedded multimedia products where pipeline behavior can be adjusted through configuration instead of hardcoded application logic.
Overview
The Rust Media Server demonstrates how developers can use the GstD Rust API to control GStreamer pipelines programmatically.
At a high level, the application:
- Reads a main YAML configuration file.
- Loads media source configuration files.
- Loads reusable feature pipeline templates.
- Creates and plays enabled GStreamer pipelines through GstD.
- Creates output directories for recordings and snapshots.
- Writes application logs to a configurable log file.
- Allows each source to enable or disable features independently.
This architecture separates the application logic from the media pipeline definitions:
- Rust manages the application logic, configuration, and orchestration.
- GstD manages pipeline creation, execution, and control.
- GStreamer performs the actual multimedia processing.
- GstInterpipe allows feature pipelines to connect to source pipelines in a reusable way.
Why Use a Media Server?
The Media Server is useful for developers and companies building configurable multimedia applications.
Typical use cases include:
- Camera management applications
- Live streaming systems
- Recording services
- Snapshot capture services
- Embedded video products
- Edge AI and computer vision systems
- Robotics and teleoperation applications
- Industrial inspection platforms
- Multi-source video applications
- Custom GStreamer orchestration services
By using the GstD Rust API, applications can create, play, stop, and inspect pipelines from Rust while keeping the codebase modular, maintainable, and easier to extend.
Requirements
The Rust Media Server requires the following components:
GStreamer
Install GStreamer version 1.24 or newer.
The example pipelines are designed for GStreamer 1.24 or later. Older versions may require changes to some pipeline elements.
Install the required packages with:
sudo apt update sudo apt install -y pkg-config curl build-essential sudo apt install -y \ libgstreamer1.0-dev \ gstreamer1.0-tools \ gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good \ gstreamer1.0-plugins-bad \ gstreamer1.0-plugins-ugly
Rust
Install Rust using rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation, make sure Cargo is available in your shell:
cargo --version
GStreamer Daemon
Install GstD following the official build instructions Building GStreamer Daemon
The media server communicates with GstD using RidgeRun's GstD Rust API.
GstInterpipe
Install GstInterpipe following the official build instructions Building GstInterpipe
GstInterpipe is used to connect source pipelines with feature pipelines such as streaming, recording, or snapshot capture.
Repository Layout
The media server executable entry point is located at:
src/bin/media_server.rs
The application uses YAML configuration files to define the media server behavior.
A typical configuration layout includes:
cfg/
├── features
│ ├── recording.yaml
│ ├── snapshot.yaml
│ └── streaming.yaml
├── media_server.yaml
└── sources
├── source_cam0.yaml
└── source_cam1.yaml
Building the Media Server
Clone the Rust Media Server Repository:
git clone https://github.com/RidgeRun/rust-media-server.git cd rust-media-server
Build the media server executable with Cargo:
cargo build --bin media_server
The debug binary is generated under:
target/debug/media_server
To build an optimized release binary:
cargo build --release --bin media_server
The release binary is generated under:
target/release/media_server
Running the Media Server
Command Line Options
The media server accepts the following command line options:
| Option | Description |
|---|---|
-c, --config <PATH>
|
Path to the main YAML configuration file. |
-l, --log-file <PATH>
|
Path to the application log file. |
-v, --log-level <0..4>
|
Application log verbosity level. |
--log-append <true or false>
|
Whether to append to the existing log file or overwrite it on startup. |
Log levels:
| Value | Level |
|---|---|
0
|
KNone
|
1
|
KError
|
2
|
KWarning
|
3
|
KInfo
|
4
|
KDebug
|
The media server can be started with the default configuration:
cargo run --bin media_server
The default runtime values are:
| Parameter | Default value |
|---|---|
| Configuration file | cfg/media_server.yaml
|
| Log file | media_server.log
|
| Log level | 4 / Debug
|
| Log append mode | true
|
To run the media server with GStreamer debug output enabled:
GST_DEBUG=2 cargo run --bin media_server
Example using custom runtime parameters:
cargo run --bin media_server -- \ --config cfg/media_server.yaml \ --log-file /tmp/media_server.log \ --log-level 3 \ --log-append false
Configuration Files
The media server is configured through YAML files.
The configuration is split into three main parts:
- Main media server configuration
- Source configuration files
- Feature template files
Main Configuration File
The main configuration file defines:
- The list of media source configuration files.
- The mapping between feature names and feature template files.
Example:
server: name: "media_server" sources: - file: "sources/source_cam0.yaml" - file: "sources/source_cam1.yaml" features: recording: "features/recording.yaml" snapshot: "features/snapshot.yaml" streaming: "features/streaming.yaml"
Each source file defines one media source and the features enabled for that source.
Each feature file defines a reusable pipeline template.
Source Configuration Files
A source configuration file describes an individual media source.
This can be a camera, a test source, a network stream, or another GStreamer-compatible input.
Example:
source:
id: "cam0"
name: "front_camera"
enabled: true
interpipe:
interpipe_sink: "cam0_sink"
source_pipeline:
pipeline_id: "cam0_source"
description: >
videotestsrc is-live=true !
video/x-raw,width=640,height=480,framerate=30/1,format=NV12 !
queue max-size-buffers=1 leaky=downstream !
videoconvertscale !
interpipesink name=${interpipe_sink} sync=false async=false
features:
recording:
enabled: false
pipeline_id: "cam0_recording"
overrides:
filename: "recordings/cam0_recording_%05d.mp4"
snapshot:
enabled: false
pipeline_id: "cam0_snapshot"
overrides:
filename: "snapshots/cam0_snapshot_%05d.jpg"
streaming:
enabled: true
pipeline_id: "cam0_stream"
overrides:
port: "5005"
The source.enabled field controls whether the source pipeline is created and played.
Each feature also has its own enabled field, allowing features to be enabled or disabled per source.
Feature Template Files
Feature templates define reusable pipeline snippets.
These templates use placeholders that are replaced with values from the source configuration file.
For example, a streaming template may look like:
streaming:
pipeline_template: >
interpipesrc listen-to=${interpipe_sink} is-live=true allow-renegotiation=true format=time !
queue max-size-buffers=1 leaky=downstream !
videoconvertscale !
queue max-size-buffers=1 leaky=downstream !
x264enc tune=zerolatency bitrate=2000 speed-preset=veryfast !
h264parse !
rtph264pay config-interval=1 pt=96 !
udpsink host=127.0.0.1 port=${port}
The values for ${interpipe_sink} and ${port} are provided by each source configuration file.
A recording template may look like:
recording:
pipeline_template: >
interpipesrc listen-to=${interpipe_sink} is-live=true allow-renegotiation=true format=time !
queue max-size-buffers=1 leaky=downstream !
videoconvertscale !
queue max-size-buffers=1 leaky=downstream !
x264enc tune=zerolatency bitrate=2000 speed-preset=veryfast !
h264parse config-interval=1 !
splitmuxsink location=${filename} max-size-time=5000000000 muxer-factory=mp4mux
A snapshot template may look like:
snapshot:
pipeline_template: >
interpipesrc listen-to=${interpipe_sink} is-live=true allow-renegotiation=true format=time !
queue max-size-buffers=1 leaky=downstream !
videoconvertscale !
videorate !
video/x-raw,framerate=1/10 !
jpegenc !
multifilesink location=${filename}
These examples can be adapted to match the requirements of the target application.
Enabling and Disabling Pipelines
The media server allows complete sources or individual features to be enabled or disabled through configuration.
Disable a Source
To disable an entire source:
source: enabled: false
When a source is disabled, the media server will not create or play that source pipeline.
Disable a Feature
To disable a feature for a specific source:
features:
streaming:
enabled: false
This allows each source to use a different set of capabilities.
For example:
- One source may only stream.
- Another source may stream and record.
- Another source may only capture snapshots.
Example: Live Streaming
The live streaming feature in the media server will create a stream via UDP on a specific port and the following receiver pipeline can be used to visualize the stream:
gst-launch-1.0 -e \ udpsrc port=5005 ! \ application/x-rtp,media=video,payload=96,clock-rate=90000,encoding-name=H264 ! \ rtpjitterbuffer latency=0 ! \ rtph264depay ! \ h264parse ! \ avdec_h264 ! \ queue max-size-buffers=1 leaky=downstream ! \ videoconvert ! \ autovideosink sync=false

For the default configuration, you should expect a videotestsrc pattern displayed as in the image above.
Example: Recording
When the media server starts, and recordings are enabled, the resulting files are written to the configured output location, The default config creates a new recording every 5 seconds.
By default, the media server creates a recordings/ directory on startup.
Example: Snapshot
When the media server starts, and snapshots are enabled, the resulting files are written to the configured output location, the default configuration creates a new snapshot every 10 seconds.
By default, the media server creates a snapshots/ directory on startup.
Example: Add a Custom Override
Feature templates can be extended by adding new placeholders.
For example, a recording template can expose the segment duration as a configurable value, see the following diff that adds the placeholder to the feature and the override to the source config file:
diff --git a/cfg/features/recording.yaml b/cfg/features/recording.yaml
index af9725a..845dd54 100644
--- a/cfg/features/recording.yaml
+++ b/cfg/features/recording.yaml
@@ -6,4 +6,4 @@ recording:
queue max-size-buffers=1 leaky=downstream !
x264enc tune=zerolatency bitrate=2000 speed-preset=veryfast !
h264parse config-interval=1 !
- splitmuxsink location=${filename} max-size-time=5000000000 muxer-factory=mp4mux
\ No newline at end of file
+ splitmuxsink location=${filename} max-size-time=${duration} muxer-factory=mp4mux
diff --git a/cfg/sources/source_cam0.yaml b/cfg/sources/source_cam0.yaml
index ed173b9..de2a59e 100644
--- a/cfg/sources/source_cam0.yaml
+++ b/cfg/sources/source_cam0.yaml
@@ -17,10 +17,11 @@ source:
features:
recording:
- enabled: false
+ enabled: true
pipeline_id: "cam0_recording"
overrides:
filename: "recordings/cam0_recording_%05d.mp4"
+ duration: "5000000000"
snapshot:
enabled: false
After changing YAML configuration files, restart the media server to apply the new pipeline set.
Output Directories
On startup, the media server creates output directories used by enabled features.
Default output directories include:
recordings/ snapshots/
Recording files and snapshot files are saved in these directories when the corresponding features are enabled.
Stopping the Media Server
Stop the media server with:
Ctrl+C
The media server will stop running when the process receives the interrupt signal.
Development Checks
The project can use pre-commit hooks to run formatting and lint checks before commits.
Install the hooks with:
pre-commit install
Configured checks include:
cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings
These checks help keep the project formatted and maintainable.
Notes and Recommendations
- Use GStreamer 1.24 or newer for the provided example pipelines.
- Make sure GstD is installed and running before starting the media server.
- Make sure GstInterpipe is installed when using source and feature pipelines connected through interpipes.
- Restart the media server after changing YAML configuration files.
- Use application logs and
GST_DEBUGoutput when debugging pipeline issues.
Extending the Media Server
The media server can be extended by adding new feature templates.
Possible extensions include:
- RTSP streaming
- WebRTC streaming
- AI inference pipelines
- Metadata extraction
- Object detection overlays
- Multi-resolution streaming
- Hardware-accelerated encoding
- Event-triggered recording
- Pipeline analytics with RidgeRun GStreamer Analytics
Because the media behavior is defined through configuration and reusable templates, some capabilities can be added without redesigning the application while others can require some source code changes. If you are interested in support for creating a media server tailored to your specifications, feel free to contact us:
Conclusion
The Rust Media Server shows how RidgeRun's GstD Rust API can be used to build configurable, modular, and maintainable GStreamer-based applications.
It provides a practical foundation for developers building media systems where sources, outputs, and processing features need to be adjusted through configuration. By combining Rust, GstD, GStreamer, and GstInterpipe, developers can build reliable media applications while keeping pipeline control clean and reusable.
For companies developing camera products, video-streaming platforms, embedded multimedia systems, or custom GStreamer applications, RidgeRun can help design, implement, optimize, and deploy production-ready solutions using Rust and GstD.
FAQ
- What is the Rust Media Server?
- The Rust Media Server is a Rust-based application that uses RidgeRun's GstD Rust API to configure, launch, and manage GStreamer media pipelines.
- What is the purpose of the media server?
- The media server provides a reusable foundation for building configurable multimedia applications. Instead of hardcoding every GStreamer pipeline in the application, developers can define sources and features through YAML configuration files.
- What can I use the media server for?
- Typical use cases include camera applications, live streaming systems, recording services, snapshot capture services, embedded multimedia products, robotics, teleoperation, edge AI, computer vision, and multi-source video applications.
- Why does the media server use GstD?
- The media server uses GstD so that Rust code can create, play, stop, and manage GStreamer pipelines programmatically through the GstD Rust API. This keeps application logic separate from the pipeline execution layer.
- Why does the media server use GstInterpipe?
- GstInterpipe allows reusable feature pipelines to consume media from source pipelines. For example, a camera source can feed independent streaming, recording, or snapshot pipelines through an interpipe connection.
- What should I check if the media server does not start correctly?
- Check that GStreamer 1.24 or newer is installed, GstD is installed, GstInterpipe is installed, the YAML files are valid, and the configured pipeline elements are available on the system. Application logs and
GST_DEBUGoutput are useful for debugging startup and pipeline issues. - What should I check if streaming does not work?
- Verify that the streaming feature is enabled for the source, the UDP port is correct, the receiver pipeline is listening on the same port, and no firewall or network configuration is blocking UDP traffic. Also confirm that the source pipeline and interpipe sink name match the values used by the streaming template.
- What should I check if recordings or snapshots are not created?
- Verify that the corresponding feature is enabled, the output directory exists or can be created, the configured filename path is valid, and the media server has permission to write to that location.
- Can I add new features besides streaming, recording, and snapshots?
- Yes. The media server can be extended with additional feature templates. A feature template is a reusable GStreamer pipeline that can be attached to one or more sources through Interpipe and configured with per-source overrides. Possible extensions include RTSP streaming, WebRTC streaming, AI inference, metadata extraction, object detection overlays, multi-resolution streaming, hardware-accelerated encoding, event-triggered recording, and analytics pipelines, depending on the required GStreamer plugins and any additional control logic needed.
- Can I use hardware-accelerated encoders?
- Yes. The example templates use software encoding, but the pipeline templates can be adapted to use platform-specific hardware encoders when available.
- Can this media server be used in production applications?
- The media server provides a practical foundation for configurable media applications. Production deployments may require additional work such as error recovery, service management, health monitoring, security, authentication, hardware-specific optimization, and deployment integration.
- Is the media server platform agnostic? Can it run on Jetson?
- Yes. The media server is written in Rust and manages GStreamer pipelines through GstD, so it can run on Linux platforms where Rust, GStreamer, GstD, and the required plugins are available. It can run on NVIDIA Jetson devices, but the pipeline templates may need to be adapted to use Jetson-specific elements such as hardware decoders, converters, and encoders.