gstreamer-rs/examples/src/bin/discoverer.rs
Otavio Salvador 2022890766 examples: Move out from 'failure' crate as it is deprecated
The 'failure' crate has been stale for quite some time and better
alternatives has been developed since its introduction. We choose the
'anyhow' and 'derive_more' to replace it.
2020-05-04 11:16:50 -03:00

109 lines
3.1 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).
extern crate gstreamer as gst;
extern crate gstreamer_pbutils as pbutils;
use crate::pbutils::prelude::*;
use crate::pbutils::DiscovererInfo;
use crate::pbutils::DiscovererStreamInfo;
use anyhow::Error;
use derive_more::{Display, Error};
use std::env;
#[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.get_tags();
match tags {
Some(taglist) => {
println!(" {}", taglist.to_string()); // FIXME use an iterator
}
None => {
println!(" no tags");
}
}
}
fn print_stream_info(stream: &DiscovererStreamInfo) {
println!("Stream: ");
if let Some(id) = stream.get_stream_id() {
println!(" Stream id: {}", id);
}
let caps_str = match stream.get_caps() {
Some(caps) => caps.to_string(),
None => String::from("--"),
};
println!(" Format: {}", caps_str);
}
fn print_discoverer_info(info: &DiscovererInfo) -> Result<(), Error> {
let uri = info
.get_uri()
.ok_or(DiscovererError("URI should not be null"))?;
println!("URI: {}", uri);
println!("Duration: {}", info.get_duration());
print_tags(info);
print_stream_info(
&info
.get_stream_info()
.ok_or(DiscovererError("Error while obtaining stream info"))?,
);
let children = info.get_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 = 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 environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}