temporary fix for syncing frames

This commit is contained in:
jazzfool 2020-08-23 00:18:12 +10:00
parent 8361c52d67
commit 153a84d85c
2 changed files with 13 additions and 1 deletions

View file

@ -16,6 +16,7 @@ Features:
- Small (around 300 lines). - Small (around 300 lines).
Limitations (hopefully to be fixed): Limitations (hopefully to be fixed):
- Lazy frame syncing. Playback is usually a few frames and the decoder and audio runs ahead. Seeking is also latent.
- GStreamer is a bit annoying to set up on Windows. - GStreamer is a bit annoying to set up on Windows.
This is a "composable" instead of a `iced::Widget`. This is because `Widget`s don't support subscriptions (yet?). Once Iced gets animation support (i.e. widgets scheduling a time to update), this can become a widget. This is a "composable" instead of a `iced::Widget`. This is because `Widget`s don't support subscriptions (yet?). Once Iced gets animation support (i.e. widgets scheduling a time to update), this can become a widget.

View file

@ -46,6 +46,9 @@ pub struct VideoPlayer {
frame_rx: crossbeam_channel::Receiver<img::Handle>, frame_rx: crossbeam_channel::Receiver<img::Handle>,
frame: Option<img::Handle>, frame: Option<img::Handle>,
pause: bool, pause: bool,
// if true, then the playback resets to the most recent frame.
// set this to true whenever playback is changed (e.g. pause, seek, etc).
reset: bool,
} }
impl Drop for VideoPlayer { impl Drop for VideoPlayer {
@ -162,6 +165,7 @@ impl VideoPlayer {
frame_rx, frame_rx,
frame: None, frame: None,
pause: false, pause: false,
reset: true,
}) })
} }
@ -201,6 +205,7 @@ impl VideoPlayer {
/// Set if the media is paused or not. /// Set if the media is paused or not.
pub fn set_paused(&mut self, pause: bool) { pub fn set_paused(&mut self, pause: bool) {
self.reset = true;
self.pause = pause; self.pause = pause;
self.source self.source
.set_state(if pause { .set_state(if pause {
@ -221,6 +226,7 @@ impl VideoPlayer {
/// ///
/// The position is converted to nanoseconds, so any duration with values more significant that nanoseconds is truncated. /// The position is converted to nanoseconds, so any duration with values more significant that nanoseconds is truncated.
pub fn seek(&mut self, position: std::time::Duration) -> Result<(), Error> { pub fn seek(&mut self, position: std::time::Duration) -> Result<(), Error> {
self.reset = true;
self.source.seek_simple( self.source.seek_simple(
gst::SeekFlags::empty(), gst::SeekFlags::empty(),
gst::GenericFormattedValue::Time(gst::ClockTime::from_nseconds( gst::GenericFormattedValue::Time(gst::ClockTime::from_nseconds(
@ -254,7 +260,12 @@ impl VideoPlayer {
} }
} }
if let Ok(frame) = self.frame_rx.try_recv() { if self.reset {
self.reset = false;
if let Some(frame) = self.frame_rx.iter().nth(self.frame_rx.len() - 1) {
self.frame = Some(frame);
}
} else if let Ok(frame) = self.frame_rx.try_recv() {
self.frame = Some(frame); self.frame = Some(frame);
} }
} }