From 52effa6efba5449de8e119392464606decfc73df Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 6 Oct 2024 11:01:01 -0600 Subject: [PATCH] Improve seek, add key bind for play/pause --- src/gstreamer/mod.rs | 55 +++++++++++++++++++++----------------------- src/key_bind.rs | 1 + 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/gstreamer/mod.rs b/src/gstreamer/mod.rs index d3deb66..6c81305 100644 --- a/src/gstreamer/mod.rs +++ b/src/gstreamer/mod.rs @@ -71,6 +71,7 @@ pub fn main() -> Result<(), Box> { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Action { + PlayPause, SeekBackward, SeekForward, } @@ -78,6 +79,7 @@ pub enum Action { impl Action { pub fn message(&self) -> Message { match self { + Self::PlayPause => Message::TogglePause, Self::SeekBackward => Message::SeekRelative(-10.0), Self::SeekForward => Message::SeekRelative(10.0), } @@ -115,6 +117,7 @@ pub struct App { key_binds: HashMap, video: Video, position: f64, + duration: f64, dragging: bool, audio_codes: Vec, current_audio: i32, @@ -196,12 +199,15 @@ impl Application for App { // Flags can be used to enable/disable subtitles println!("flags {:?}", pipeline.property_value("flags")); + let duration = video.duration().as_secs_f64(); + let mut app = App { core, flags, key_binds: key_binds(), video, position: 0.0, + duration, dragging: false, audio_codes, current_audio, @@ -253,20 +259,19 @@ impl Application for App { self.dragging = true; self.position = secs; self.video.set_paused(true); - self.video - .seek(Duration::from_secs_f64(self.position), true) - .expect("seek"); + let duration = Duration::try_from_secs_f64(self.position).unwrap_or_default(); + self.video.seek(duration, true).expect("seek"); } Message::SeekRelative(secs) => { - self.video - .seek(Duration::from_secs_f64(self.position + secs), true) - .expect("seek"); + self.position = self.video.position().as_secs_f64(); + let duration = + Duration::try_from_secs_f64(self.position + secs).unwrap_or_default(); + self.video.seek(duration, true).expect("seek"); } Message::SeekRelease => { self.dragging = false; - self.video - .seek(Duration::from_secs_f64(self.position), true) - .expect("seek"); + let duration = Duration::try_from_secs_f64(self.position).unwrap_or_default(); + self.video.seek(duration, true).expect("seek"); self.video.set_paused(false); } Message::EndOfStream => { @@ -314,10 +319,11 @@ impl Application for App { /// Creates a view after each update. fn view(&self) -> Element { - let format_time = |duration: Duration| -> String { - let seconds = duration.as_secs() % 60; - let minutes = (duration.as_secs() / 60) % 60; - let hours = (duration.as_secs() / 60) / 60; + let format_time = |time_float: f64| -> String { + let time = time_float.floor() as i64; + let seconds = time % 60; + let minutes = (time / 60) % 60; + let hours = (time / 60) / 60; format!("{:02}:{:02}:{:02}", hours, minutes, seconds) }; widget::container( @@ -343,24 +349,15 @@ impl Application for App { }) .on_press(Message::TogglePause), ) + .push(widget::text(format_time(self.position)).font(font::mono())) .push( - widget::text(format_time(Duration::from_secs_f64(self.position))) + Slider::new(0.0..=self.duration, self.position, Message::Seek) + .step(0.1) + .on_release(Message::SeekRelease), + ) + .push( + widget::text(format_time(self.duration - self.position)) .font(font::mono()), - ) - .push( - Slider::new( - 0.0..=self.video.duration().as_secs_f64(), - self.position, - Message::Seek, - ) - .step(0.1) - .on_release(Message::SeekRelease), - ) - .push( - widget::text(format_time( - self.video.duration() - Duration::from_secs_f64(self.position), - )) - .font(font::mono()), ), ), ) diff --git a/src/key_bind.rs b/src/key_bind.rs index 2898262..f664004 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -61,6 +61,7 @@ pub fn key_binds() -> HashMap { } //TODO: key bindings + bind!([], Key::Named(Named::Space), PlayPause); bind!([], Key::Named(Named::ArrowLeft), SeekBackward); bind!([], Key::Named(Named::ArrowRight), SeekForward);