2018-11-05 10:10:14 +00:00
|
|
|
// 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).
|
|
|
|
|
2020-10-10 08:10:20 +00:00
|
|
|
use gst_pbutils::prelude::*;
|
2018-02-19 20:15:52 +00:00
|
|
|
|
2020-10-10 08:10:20 +00:00
|
|
|
use gst_pbutils::DiscovererInfo;
|
|
|
|
use gst_pbutils::DiscovererStreamInfo;
|
2018-02-19 20:15:52 +00:00
|
|
|
|
2020-05-02 23:23:38 +00:00
|
|
|
use anyhow::Error;
|
|
|
|
use derive_more::{Display, Error};
|
2018-02-19 20:15:52 +00:00
|
|
|
|
|
|
|
use std::env;
|
|
|
|
|
|
|
|
#[path = "../examples-common.rs"]
|
|
|
|
mod examples_common;
|
|
|
|
|
2020-05-02 23:23:38 +00:00
|
|
|
#[derive(Debug, Display, Error)]
|
|
|
|
#[display(fmt = "Discoverer error {}", _0)]
|
|
|
|
struct DiscovererError(#[error(not(source))] &'static str);
|
2018-02-19 20:15:52 +00:00
|
|
|
|
|
|
|
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: ");
|
2019-02-28 08:54:32 +00:00
|
|
|
if let Some(id) = stream.get_stream_id() {
|
|
|
|
println!(" Stream id: {}", id);
|
2018-02-19 20:15:52 +00:00
|
|
|
}
|
|
|
|
let caps_str = match stream.get_caps() {
|
|
|
|
Some(caps) => caps.to_string(),
|
2018-03-02 19:06:45 +00:00
|
|
|
None => String::from("--"),
|
2018-02-19 20:15:52 +00:00
|
|
|
};
|
|
|
|
println!(" Format: {}", caps_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_discoverer_info(info: &DiscovererInfo) -> Result<(), Error> {
|
2018-07-27 10:36:40 +00:00
|
|
|
let uri = info
|
|
|
|
.get_uri()
|
2018-03-02 19:06:45 +00:00
|
|
|
.ok_or(DiscovererError("URI should not be null"))?;
|
2018-02-19 20:15:52 +00:00
|
|
|
println!("URI: {}", uri);
|
|
|
|
println!("Duration: {}", info.get_duration());
|
|
|
|
print_tags(info);
|
2018-07-27 10:36:40 +00:00
|
|
|
print_stream_info(
|
|
|
|
&info
|
|
|
|
.get_stream_info()
|
|
|
|
.ok_or(DiscovererError("Error while obtaining stream info"))?,
|
|
|
|
);
|
2018-02-19 20:15:52 +00:00
|
|
|
|
|
|
|
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);
|
2020-10-10 08:10:20 +00:00
|
|
|
let discoverer = gst_pbutils::Discoverer::new(timeout)?;
|
2018-02-19 20:15:52 +00:00
|
|
|
let info = discoverer.discover_uri(uri)?;
|
|
|
|
print_discoverer_info(&info)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn example_main() {
|
|
|
|
match run_discoverer() {
|
|
|
|
Ok(_) => (),
|
2018-03-02 19:06:45 +00:00
|
|
|
Err(e) => eprintln!("Error: {}", e),
|
2018-02-19 20:15:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2021-04-10 11:42:04 +00:00
|
|
|
// 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)
|
2018-02-19 20:15:52 +00:00
|
|
|
examples_common::run(example_main);
|
|
|
|
}
|