diff --git a/data/net.baseart.Glide.ui b/data/net.baseart.Glide.ui index b3a0219..67a85be 100644 --- a/data/net.baseart.Glide.ui +++ b/data/net.baseart.Glide.ui @@ -40,6 +40,19 @@ Video track + + Playback +
+ + Increase speed + app.speed-increase + + + Decrease speed + app.speed-decrease + +
+
Subtitles
@@ -283,6 +296,19 @@ audio-volume-medium-symbolic Mute the audio track + + + Page_Up + Increase playback speed + + + + + Page_Down + Decrease playback speed + + + diff --git a/src/channel_player.rs b/src/channel_player.rs index b1c389a..35c751a 100644 --- a/src/channel_player.rs +++ b/src/channel_player.rs @@ -576,4 +576,24 @@ impl ChannelPlayer { self.gtksink .send_event(gst::event::Step::new(Buffers::ONE, 1.0, true, false)); } + + pub fn playback_rate(&self) -> f64 { + self.player.rate() + } + + pub fn increase_speed(&self) { + let rate = self.player.rate(); + let offset = 0.25; + if rate + offset <= 2.0 { + self.player.set_rate(rate + offset); + } + } + + pub fn decrease_speed(&self) { + let rate = self.player.rate(); + let offset = 0.25; + if rate > offset { + self.player.set_rate(rate - offset); + } + } } diff --git a/src/main.rs b/src/main.rs index 749a961..cef7a2e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,6 +75,8 @@ struct VideoPlayer { audio_offset_reset_action: gio::SimpleAction, subtitle_offset_reset_action: gio::SimpleAction, video_frame_step_action: gio::SimpleAction, + speed_increase_action: gio::SimpleAction, + speed_decrease_action: gio::SimpleAction, player_receiver: Option>, } @@ -177,6 +179,12 @@ impl VideoPlayer { let video_frame_step_action = gio::SimpleAction::new("video-frame-step", None); gtk_app.add_action(&video_frame_step_action); + let speed_increase_action = gio::SimpleAction::new("speed-increase", None); + gtk_app.add_action(&speed_increase_action); + + let speed_decrease_action = gio::SimpleAction::new("speed-decrease", None); + gtk_app.add_action(&speed_decrease_action); + let about = gio::SimpleAction::new("about", None); about.connect_activate(move |_, _| { with_video_player!(video_player { @@ -248,6 +256,8 @@ impl VideoPlayer { audio_offset_reset_action, subtitle_offset_reset_action, video_frame_step_action, + speed_increase_action, + speed_decrease_action, player_receiver: Some(player_receiver), }) } @@ -471,6 +481,18 @@ impl VideoPlayer { }) }); + self.speed_decrease_action.connect_activate(|_, _| { + with_video_player!(video_player { + video_player.player.decrease_speed(); + }); + }); + + self.speed_increase_action.connect_activate(|_, _| { + with_video_player!(video_player { + video_player.player.increase_speed(); + }); + }); + let paintable = self.player.paintable(); paintable.connect_invalidate_contents(|p| { with_video_player!(video_player { @@ -542,11 +564,18 @@ impl VideoPlayer { self.ui_context.set_progress_bar_format_callback(|value| { let position = gst::ClockTime::from_seconds(value as u64); with_optional_video_player!(video_player { - if let Some(duration) = video_player.player.duration() { - format!("{position:.0} / {duration:.0}") - } else { - format!("{position:.0}") - } + let status = if let Some(duration) = video_player.player.duration() { + format!("{position:.0} / {duration:.0}") + } else { + format!("{position:.0}") + }; + // FIXME: Ideally it'd be nice to show this on an OSD overlay? + let playback_rate = video_player.player.playback_rate(); + if playback_rate != 1.0 { + format!("{status} @ {playback_rate}.x") + } else { + status + } } { format!("{position:.0}") }) diff --git a/src/ui_context.rs b/src/ui_context.rs index a3ee0b3..6723c1e 100644 --- a/src/ui_context.rs +++ b/src/ui_context.rs @@ -171,6 +171,8 @@ impl UIContext { ("dump-pipeline", ["d"]), ("show-shortcuts", ["question"]), ("video-frame-step", ["n"]), + ("speed-increase", ["Page_Up"]), + ("speed-decrease", ["Page_Down"]), ]; for (action, accels) in accels_per_action.iter() { app.set_accels_for_action(&format!("app.{action}"), accels);