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

85 lines
2.9 KiB
Rust
Raw Normal View History

// This example demonstrates how to use the gstreamer crate in conjunction
// with the future trait. The example waits for either an error to occur,
// or for an EOS message. When a message notifying about either of both
// is received, the future is resolved.
2017-07-31 13:12:08 +00:00
extern crate gstreamer as gst;
use gst::prelude::*;
2017-07-31 13:12:08 +00:00
extern crate futures;
use futures::executor::LocalPool;
use futures::future;
use futures::prelude::*;
use futures::task::SpawnExt;
2017-07-31 13:12:08 +00:00
use std::env;
2017-11-12 18:07:02 +00:00
#[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
// Read the pipeline to launch from the commandline, using the launch syntax.
2017-07-31 13:12:08 +00:00
let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" ");
gst::init().unwrap();
// Create a pipeline from the launch-syntax given on the cli.
2017-07-31 13:12:08 +00:00
let pipeline = gst::parse_launch(&pipeline_str).unwrap();
let bus = pipeline.get_bus().unwrap();
pipeline
.set_state(gst::State::Playing)
.expect("Unable to set the pipeline to the `Playing` state");
2017-07-31 13:12:08 +00:00
// Use a LocalPool as executor. This runs single threaded on this very thread.
let mut pool = LocalPool::new();
// We use an AbortHandle for having a Future that runs forever
// until we call handle.abort() to quit our event loop
let (quit_handle, quit_registration) = future::AbortHandle::new_pair();
let quit_future =
future::Abortable::new(future::pending::<()>(), quit_registration).map(|_| ());
// BusStream implements the Stream trait. Stream::for_each is calling a closure for each item
// and returns a Future that resolves when the stream is done
let messages = gst::BusStream::new(&bus).for_each(move |msg| {
use gst::MessageView;
// Determine whether we want to quit: on EOS or error message
// we quit, otherwise simply continue.
match msg.view() {
MessageView::Eos(..) => quit_handle.abort(),
MessageView::Error(err) => {
println!(
"Error from {:?}: {} ({:?})",
err.get_src().map(|s| s.get_path_string()),
err.get_error(),
err.get_debug()
);
quit_handle.abort();
2017-07-31 13:12:08 +00:00
}
_ => (),
};
// New future to resolve for each message: nothing here
future::ready(())
});
// Spawn our message handling stream
pool.spawner().spawn(messages).unwrap();
2017-07-31 13:12:08 +00:00
// And run until something is quitting the loop, i.e. an EOS
// or error message is received above
pool.run_until(quit_future);
2017-07-31 13:12:08 +00:00
pipeline
.set_state(gst::State::Null)
.expect("Unable to set the pipeline to the `Null` state");
2017-07-31 13:12:08 +00:00
}
2017-11-12 18:07:02 +00:00
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);
}