gstreamer-rs/examples/src/bin/discoverer.rs

97 lines
2.9 KiB
Rust

// This example uses gstreamer's discoverer api
// https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/GstDiscoverer.html
// To detect as much information from a given URI.
// The amount of time that the discoverer is allowed to use is limited by a timeout.
// This allows to handle e.g. network problems gracefully. When the timeout hits before
// discoverer was able to detect anything, discoverer will report an error.
// In this example, we catch this error and stop the application.
// Discovered information could for example contain the stream's duration or whether it is
// seekable (filesystem) or not (some http servers).
use std::env;
use anyhow::Error;
use derive_more::{Display, Error};
use gst_pbutils::{prelude::*, DiscovererInfo, DiscovererStreamInfo};
#[path = "../examples-common.rs"]
mod examples_common;
#[derive(Debug, Display, Error)]
#[display(fmt = "Discoverer error {_0}")]
struct DiscovererError(#[error(not(source))] &'static str);
fn print_tags(info: &DiscovererInfo) {
println!("Tags:");
let tags = info.tags();
match tags {
Some(taglist) => {
println!(" {taglist}"); // FIXME use an iterator
}
None => {
println!(" no tags");
}
}
}
fn print_stream_info(stream: &DiscovererStreamInfo) {
println!("Stream: ");
println!(" Stream id: {}", stream.stream_id());
let caps_str = match stream.caps() {
Some(caps) => caps.to_string(),
None => String::from("--"),
};
println!(" Format: {caps_str}");
}
fn print_discoverer_info(info: &DiscovererInfo) -> Result<(), Error> {
println!("URI: {}", info.uri());
println!("Duration: {}", info.duration().display());
print_tags(info);
print_stream_info(
&info
.stream_info()
.ok_or(DiscovererError("Error while obtaining stream info"))?,
);
let children = info.stream_list();
println!("Children streams:");
for child in children {
print_stream_info(&child);
}
Ok(())
}
fn run_discoverer() -> Result<(), Error> {
gst::init()?;
let args: Vec<_> = env::args().collect();
let uri: &str = if args.len() == 2 {
args[1].as_ref()
} else {
println!("Usage: discoverer uri");
std::process::exit(-1)
};
let timeout: gst::ClockTime = gst::ClockTime::from_seconds(15);
let discoverer = gst_pbutils::Discoverer::new(timeout)?;
let info = discoverer.discover_uri(uri)?;
print_discoverer_info(&info)?;
Ok(())
}
fn example_main() {
match run_discoverer() {
Ok(_) => (),
Err(e) => eprintln!("Error: {e}"),
}
}
fn main() {
// tutorials_common::run is only required to set up the application environment on macOS
// (but not necessary in normal Cocoa applications where this is set up automatically)
examples_common::run(example_main);
}