diff --git a/backends/gstreamer/src/player.rs b/backends/gstreamer/src/player.rs index 7f7b6967..9f65f1aa 100644 --- a/backends/gstreamer/src/player.rs +++ b/backends/gstreamer/src/player.rs @@ -163,6 +163,13 @@ impl GStreamerPlayer { .set_property("uri", &Value::from("appsrc://")) .map_err(|e| BackendError::SetPropertyFailed(e.0))?; + // Set position interval update to 0.5 seconds. + let mut config = player.get_config(); + config.set_position_update_interval(500u32); + player + .set_config(config) + .map_err(|e| BackendError::SetPropertyFailed(e.0))?; + let video_sink = gst::ElementFactory::make("appsink", None) .ok_or(BackendError::ElementCreationFailed("appsink"))?; let pipeline = player.get_pipeline(); @@ -224,6 +231,18 @@ impl GStreamerPlayer { } }); + let inner_clone = inner.clone(); + inner + .lock() + .unwrap() + .player + .connect_position_updated(move |_, position| { + if let Some(seconds) = position.seconds() { + let inner = inner_clone.lock().unwrap(); + inner.notify(PlayerEvent::PositionChanged(seconds)); + } + }); + let inner_clone = inner.clone(); inner .lock() @@ -239,15 +258,36 @@ impl GStreamerPlayer { } }); + let inner_clone = inner.clone(); inner .lock() .unwrap() .player .connect_duration_changed(move |_, duration| { - let mut seconds = duration / 1_000_000_000; - let mut minutes = seconds / 60; - seconds %= 60; - minutes %= 60; + let duration = if duration != gst::ClockTime::none() { + let nanos = duration.nanoseconds(); + if nanos.is_none() { + eprintln!("Could not get duration nanoseconds"); + return; + } + let seconds = duration.seconds(); + if seconds.is_none() { + eprintln!("Could not get duration seconds"); + return; + } + Some(time::Duration::new(seconds.unwrap(), (nanos.unwrap() % 1_000_000_000) as u32)) + } else { + None + }; + let mut inner = inner_clone.lock().unwrap(); + let mut updated_metadata = None; + if let Some(ref mut metadata) = inner.last_metadata { + metadata.duration = duration; + updated_metadata = Some(metadata.clone()); + } + if updated_metadata.is_some() { + inner.notify(PlayerEvent::MetadataUpdated(updated_metadata.unwrap())); + } }); let inner_clone = inner.clone(); diff --git a/examples/player/main.rs b/examples/player/main.rs index 06808e1f..f07fc1bf 100644 --- a/examples/player/main.rs +++ b/examples/player/main.rs @@ -117,6 +117,7 @@ impl PlayerWrapper { println!("Player state changed to {:?}", s); } PlayerEvent::FrameUpdated => eprint!("."), + PlayerEvent::PositionChanged(_) => (), } } player.lock().unwrap().stop().unwrap(); diff --git a/examples/simple_player.rs b/examples/simple_player.rs index 8f5e6c80..64ed53bc 100644 --- a/examples/simple_player.rs +++ b/examples/simple_player.rs @@ -94,6 +94,7 @@ fn run_example(servo_media: Arc) { println!("Player state changed to {:?}", s); } PlayerEvent::FrameUpdated => eprint!("."), + PlayerEvent::PositionChanged(p) => println!("{:?}", p), } } diff --git a/player/src/lib.rs b/player/src/lib.rs index 944dc613..1b933c62 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -20,10 +20,11 @@ pub enum PlaybackState { #[derive(Clone, Debug, Deserialize, Serialize)] pub enum PlayerEvent { EndOfStream, + Error, + FrameUpdated, MetadataUpdated(metadata::Metadata), + PositionChanged(u64), StateChanged(PlaybackState), - FrameUpdated, - Error, } pub trait Player: Send {