Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ed182a1
Add Cargo.toml for Rust Client
lmerayo1 Mar 27, 2026
5e41bd0
Add Rust client source code
lmerayo1 Mar 27, 2026
1caf51e
Add examples for Rust client
lmerayo1 Mar 27, 2026
e6ae8dd
Update license header
lmerayo1 Mar 31, 2026
aa3275c
use Atomic bool as stop flag for thread
lmerayo1 Mar 31, 2026
0c57b97
Use pattern matching instead of if-else
lmerayo1 Mar 31, 2026
c7ad404
Rename examples and add missing meson.build files
lmerayo1 Mar 31, 2026
09fb394
Keep ConnectionSettings in transport struct
lmerayo1 Mar 31, 2026
f5ec760
Fix typo
lmerayo1 Mar 31, 2026
2fac0a5
Replace Status with an enum
lmerayo1 Mar 31, 2026
0ae81b7
Remove unnecessary socket reconnection attempt
lmerayo1 Mar 31, 2026
9c78186
Refactor timeout calculation
lmerayo1 Mar 31, 2026
9586059
Reformat Rust library building in Meson
lmerayo1 Mar 31, 2026
157f066
Use CamelCase in Rust Status enum values
lmerayo1 Mar 31, 2026
8c26a02
Add README with how to run Rust examples
lmerayo1 Mar 31, 2026
a549459
Add constants for seek function
lmerayo1 May 11, 2026
2997bd5
Reformat Status::BusTimeout as error
lmerayo1 May 15, 2026
76a1631
Fix return of cmd_update
lmerayo1 May 15, 2026
6f46532
Treat Status::BusTimeout as error
lmerayo1 May 15, 2026
c4b4a7e
Remove repeated function calls
lmerayo1 May 15, 2026
dbb418b
Rewrite cmd_send and fix return errors
lmerayo1 May 15, 2026
8d7f461
Remove meson build logic for Rust API
lmerayo1 May 18, 2026
4c58a72
Replace custom json handling logic for serde_json dep
lmerayo1 May 18, 2026
0be7a58
Replace gstc_rust with gstc for the crate name
lmerayo1 May 19, 2026
0667e3a
Fix recording artifact save location
lmerayo1 May 19, 2026
42c2098
Add root Cargo files
lmerayo1 May 19, 2026
a0cb09c
Update documentation
lmerayo1 May 19, 2026
5ef83e2
Apply format to rust files
lmerayo1 May 19, 2026
cdf6c7f
Add is-live=true to avoid consuming CPU
lmerayo1 May 27, 2026
206f7ef
Remove character escaping
lmerayo1 May 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ autoregen.sh
# debian files
*.deb
*.build
!**/meson.build
*.buildinfo
*.changes
debian/.debhelper/
Expand Down
105 changes: 105 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[workspace]
members = [
"libgstc/rust/gstc",
]
resolver = "2"
67 changes: 67 additions & 0 deletions examples/libgstc/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Rust `libgstc` Examples

These examples show how to control GStreamer Daemon (`gstd`) using the Rust `gstc` client library.

## Prerequisites

- `gstd` must be running and listening on `127.0.0.1:5000`
- Rust examples assume the daemon is reachable at that address and port
- Some examples require GStreamer plugins such as `autovideosink`, `playbin`, `qtmux`, `avenc_mpeg4`, and `lamemp3enc`

## How to Build
To build the examples, run the following command from the repository root:
```bash
cargo build --examples
```
The examples will be available at the following path:
```bash
target/debug/examples/
```

## How To Run

You can run the examples directly as an executable or
with Cargo from the Repository root:

```bash
cargo run --example simple_pipeline
```

Examples that take an argument can be run like this:

```bash
cargo run --example gapless_playback -- /path/to/video.mp4
```

## Examples

### `simple_pipeline`

Creates a `videotestsrc ! autovideosink` pipeline, starts playback, waits for Enter, then stops and deletes the pipeline.

### `pipeline_lifecycle`

Creates a `videotestsrc ! fakesink` pipeline, sets it to `PLAYING`, polls until the daemon reports the expected state, then stops and deletes the pipeline.

### `wait_on_bus`

Creates a finite pipeline with `videotestsrc num-buffers=300`, waits for an EOS message on the bus, prints the raw bus message, then cleans up the pipeline.

### `dynamic_property_change`

Creates a `videotestsrc` pipeline and changes the `pattern` property once per second while the pipeline is running. Press Enter to stop it.

### `gapless_playback`

Plays a media file with `playbin`, waits for EOS, then seeks back to the start to continue playback. Press Enter to stop it.

Run with:

```bash
cargo run --example gapless_playback -- /path/to/video.mp4
```

### `mp4_recording`

Creates a live audio/video recording pipeline that writes to `mp4_recording.mp4`. When you press Enter, it injects EOS, waits for the EOS bus message, then stops and deletes the pipeline.

65 changes: 65 additions & 0 deletions examples/libgstc/rust/dynamic_property_change_rust.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* This file is part of GStreamer Daemon
* Copyright 2015-2026 RidgeRun, LLC (http://www.ridgerun.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

use gstc::{Client, Status};
use std::io;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

fn main() -> Result<(), Status> {
let client = Client::new("127.0.0.1", 5000, -1, true)?;

client.pipeline_create("pipe", "videotestsrc name=vts ! autovideosink")?;
println!("Pipeline created successfully!");

client.pipeline_play("pipe")?;
println!("Pipeline set to playing!");

println!("Press enter to stop the pipeline...");
let stop_flag = Arc::new(AtomicBool::new(false));
let thread_stop_flag = Arc::clone(&stop_flag);
thread::spawn(move || {
let mut line = String::new();
let _ = io::stdin().read_line(&mut line);
thread_stop_flag.store(true, Ordering::Relaxed);
});

let mut format = 0;
loop {
client.element_set("pipe", "vts", "pattern", &format.to_string())?;
format = (format + 1) % 10;

if stop_flag.load(Ordering::Relaxed) {
break;
}

thread::sleep(Duration::from_secs(1));
}

client.pipeline_stop("pipe")?;
println!("Pipeline set to null!");

client.pipeline_delete("pipe")?;
println!("Pipeline deleted!");

Ok(())
}
90 changes: 90 additions & 0 deletions examples/libgstc/rust/gapless_playback_rust.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* This file is part of GStreamer Daemon
* Copyright 2015-2026 RidgeRun, LLC (http://www.ridgerun.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

use gstc::{Client, Status};
use std::env;
use std::io;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;

const RATE: f64 = 1.0;
const FORMAT: i32 = 3;
const FLAGS: i32 = 1;
const START_TYPE: i32 = 1;
const START: i64 = 0;
const STOP_TYPE: i32 = 1;
const STOP: i64 = -1;

fn main() -> Result<(), Status> {
let video = match env::args().nth(1) {
Some(path) => path,
None => {
eprintln!("Please provide a video to play");
return Err(Status::NullArgument);
}
};

let abs_path = PathBuf::from(&video)
.canonicalize()
.unwrap_or_else(|_| PathBuf::from(&video));
let uri = format!("file://{}", abs_path.display());

let client = Client::new("127.0.0.1", 5000, -1, true)?;

client.pipeline_create("pipe", &format!("playbin uri={}", uri))?;
println!("Pipeline created successfully!");

client.pipeline_play("pipe")?;
println!("Pipeline set to playing!");

println!("Press enter to stop the pipeline...");
let stop_flag = Arc::new(AtomicBool::new(false));
let thread_stop_flag = Arc::clone(&stop_flag);
thread::spawn(move || {
let mut line = String::new();
let _ = io::stdin().read_line(&mut line);
thread_stop_flag.store(true, Ordering::Relaxed);
});

while !stop_flag.load(Ordering::Relaxed) {
let message = client.pipeline_bus_wait("pipe", "eos", -1)?;
if message.status != Status::Ok {
eprintln!("Unable to read from bus: {}", message.status.code());
break;
}

println!("EOS message received!");

client.pipeline_seek(
"pipe", RATE, FORMAT, FLAGS, START_TYPE, START, STOP_TYPE, STOP,
)?;
println!("Pipeline reset!");
}

client.pipeline_stop("pipe")?;
println!("Pipeline set to null!");

client.pipeline_delete("pipe")?;
println!("Pipeline deleted!");

Ok(())
}
Loading
Loading