From 9357c98521a1e8c200b5d55c17c2e0d895c965f9 Mon Sep 17 00:00:00 2001 From: Erica Z Date: Sun, 3 Nov 2024 19:25:32 +0100 Subject: [PATCH] fix playbar seek position --- resources/playbar.blp | 23 ++++++++++++----------- src/mpv/error.rs | 2 +- src/mpv/format.rs | 23 +++++++++++++++++++++++ src/playbin2.rs | 2 +- src/ui/playbar.rs | 4 ++++ src/ui/window.rs | 28 ++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 13 deletions(-) diff --git a/resources/playbar.blp b/resources/playbar.blp index c357af6..9ac3ea5 100644 --- a/resources/playbar.blp +++ b/resources/playbar.blp @@ -66,7 +66,7 @@ template $AudreyUiPlaybar: Adw.Bin { "numeric", ] - label: bind $format_timestamp (template.playbin as <$AudreyPlaybin>.position) as ; + label: bind $format_timestamp (template.position) as ; } [center] @@ -74,12 +74,12 @@ template $AudreyUiPlaybar: Adw.Bin { name: "seek-scale"; orientation: horizontal; width-request: 400; - sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + //sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; adjustment: Adjustment { lower: 0; - value: bind template.playbin as <$AudreyPlaybin>.position; - upper: bind template.playbin as <$AudreyPlaybin>.duration; + value: bind template.position; + upper: bind template.duration; }; change-value => $on_play_position_seek () swapped; @@ -92,7 +92,7 @@ template $AudreyUiPlaybar: Adw.Bin { "numeric", ] - label: bind $format_timestamp (template.playbin as <$AudreyPlaybin>.duration) as ; + label: bind $format_timestamp (template.duration) as ; } } @@ -103,7 +103,7 @@ template $AudreyUiPlaybar: Adw.Bin { Button { icon-name: "media-skip-backward"; valign: center; - sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + //sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; clicked => $on_skip_backward_clicked () swapped; } @@ -111,15 +111,16 @@ template $AudreyUiPlaybar: Adw.Bin { Button { icon-name: "media-seek-backward"; valign: center; - sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + //sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; clicked => $seek_backward () swapped; } Button { - icon-name: bind $play_pause_icon_name (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + icon-name: "media-playback-start"; + //icon-name: bind $play_pause_icon_name (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; valign: center; - sensitive: bind $can_press_play (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>, template.playbin as <$AudreyPlaybin>.play-queue-length) as ; + //sensitive: bind $can_press_play (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>, template.playbin as <$AudreyPlaybin>.play-queue-length) as ; clicked => $on_play_pause_clicked () swapped; } @@ -127,7 +128,7 @@ template $AudreyUiPlaybar: Adw.Bin { Button { icon-name: "media-seek-forward"; valign: center; - sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + //sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; clicked => $seek_forward () swapped; } @@ -135,7 +136,7 @@ template $AudreyUiPlaybar: Adw.Bin { Button { icon-name: "media-skip-forward"; valign: center; - sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; + //sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as ; clicked => $on_skip_forward_clicked () swapped; } diff --git a/src/mpv/error.rs b/src/mpv/error.rs index 13343be..eb7c604 100644 --- a/src/mpv/error.rs +++ b/src/mpv/error.rs @@ -3,7 +3,7 @@ use std::ffi::{c_int, CStr}; use std::fmt; #[derive(Copy, Clone)] -pub struct Error(c_int); +pub struct Error(pub(super) c_int); impl Error { pub(super) fn from_return_code(rc: c_int) -> Result<(), Self> { diff --git a/src/mpv/format.rs b/src/mpv/format.rs index b51d02f..b8043f7 100644 --- a/src/mpv/format.rs +++ b/src/mpv/format.rs @@ -122,6 +122,19 @@ impl GetProperty for i64 { } } +impl GetProperty for f64 { + unsafe fn get_property(ctx: *mut ffi::mpv_handle, name: *const c_char) -> Result { + let mut value: f64 = 0.0; + Error::from_return_code(ffi::mpv_get_property( + ctx, + name, + ffi::mpv_format_MPV_FORMAT_DOUBLE, + std::ptr::from_mut::(&mut value) as *mut c_void, + ))?; + Ok(value) + } +} + impl GetProperty for String { unsafe fn get_property(ctx: *mut ffi::mpv_handle, name: *const c_char) -> Result { let mut value: *mut c_char = std::ptr::null_mut(); @@ -136,3 +149,13 @@ impl GetProperty for String { Ok(result) } } + +impl GetProperty for Option { + unsafe fn get_property(ctx: *mut ffi::mpv_handle, name: *const c_char) -> Result { + match T::get_property(ctx, name) { + Ok(t) => Ok(Some(t)), + Err(Error(ffi::mpv_error_MPV_ERROR_PROPERTY_UNAVAILABLE)) => Ok(None), + Err(err) => Err(err), + } + } +} diff --git a/src/playbin2.rs b/src/playbin2.rs index 63ab22c..8fc996a 100644 --- a/src/playbin2.rs +++ b/src/playbin2.rs @@ -95,7 +95,7 @@ where } pub fn position(&self) -> Option { - todo!() + self.mpv.get_property("time-pos").unwrap() } pub fn current_entry(&self) -> Option { diff --git a/src/ui/playbar.rs b/src/ui/playbar.rs index 698a0f7..c3c06f1 100644 --- a/src/ui/playbar.rs +++ b/src/ui/playbar.rs @@ -23,6 +23,10 @@ mod imp { volume: Cell, #[property(get, set)] mute: Cell, + #[property(get, set)] + position: Cell, + #[property(get, set)] + duration: Cell, } #[glib::object_subclass] diff --git a/src/ui/window.rs b/src/ui/window.rs index 5cb4422..a262a26 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -188,6 +188,7 @@ mod imp { use adw::prelude::*; use adw::subclass::prelude::*; use gtk::{gdk, gio, glib}; +use std::rc::Rc; glib::wrapper! { pub struct Window(ObjectSubclass) @@ -237,6 +238,33 @@ impl Window { ), ); + window.imp().playbin2.file_started().connect_object( + &*window.imp().playbar, + |playbin, playbar, ()| { + let entry = &playbin.entries()[playbin.current_entry().unwrap()]; + playbar.set_duration(entry.duration() as f64); + true + }, + ); + + // update position every 100 ms + glib::source::timeout_add_local(std::time::Duration::from_millis(100), { + let playbar = window.imp().playbar.downgrade(); + let playbin = Rc::downgrade(&window.imp().playbin2); + move || { + let playbar = match playbar.upgrade() { + None => return glib::ControlFlow::Break, + Some(playbar) => playbar, + }; + let playbin = match playbin.upgrade() { + None => return glib::ControlFlow::Break, + Some(playbin) => playbin, + }; + playbar.set_position(playbin.position().unwrap_or(0.0)); + glib::ControlFlow::Continue + } + }); + window .imp() .setup