diff --git a/src/mpris/player.rs b/src/mpris/player.rs index 50dfb02..9f72ec2 100644 --- a/src/mpris/player.rs +++ b/src/mpris/player.rs @@ -43,7 +43,7 @@ impl MetadataMap { .try_into() .unwrap() }), - //length: Some((song.duration() * MICROSECONDS) as i64), + length: Some(song.duration() * MICROSECONDS as i64), album: Some(song.album().into()), artist: Some(vec![song.artist().into()]), //content_created: song.year().map(|year| chrono::NaiveDate::from_yo_opt(year, 1).unwrap()), // FIXME: replace this unwrap with Some(Err) -> None @@ -97,7 +97,6 @@ impl MetadataMap { pub struct Player { playbin: SendWeakRef, metadata: MetadataMap, - volume: f64, } impl Player { @@ -110,7 +109,6 @@ impl Player { let player = Self { playbin: playbin.downgrade().into(), metadata: MetadataMap::from_playbin_song(None), - volume: (playbin.volume() as f64) / 100.0, }; object_server.at("/org/mpris/MediaPlayer2", player).await?; @@ -141,6 +139,24 @@ impl Player { ), ); + playbin.connect_closure( + "seeked", + false, + glib::closure_local!( + #[strong] + player_ref, + move |_playbin: &crate::Playbin, position: f64| { + let player_ref = player_ref.clone(); + glib::spawn_future_local(async move { + player_ref + .seeked((position * MICROSECONDS) as i64) + .await + .unwrap(); + }); + } + ), + ); + playbin.connect_notify_local( Some("play-queue-length"), glib::clone!( @@ -192,13 +208,10 @@ impl Player { glib::clone!( #[strong] player_ref, - move |playbin: &crate::Playbin, _| { - let playbin_volume = playbin.volume(); - + move |_playbin: &crate::Playbin, _| { let player_ref = player_ref.clone(); glib::spawn_future_local(async move { - let mut player = player_ref.get_mut().await; - player.volume = (playbin_volume as f64) / 100.0; + let player = player_ref.get_mut().await; player .volume_changed(player_ref.signal_emitter()) .await @@ -223,32 +236,43 @@ impl Player { let playbin = self.playbin.upgrade().unwrap(); if playbin.play_queue_position() + 1 > playbin.play_queue_length() { // If there is no next track (and endless playback and track repeat are both off), stop playback. - self.stop(); + // (interpret this as something else than what Stop does) + playbin.stop(); } else { playbin.go_to_next_track(); } } fn previous(&self) { + let playbin = self.playbin.upgrade().unwrap(); + // If CanGoPrevious is false, attempting to call this method should have no effect. if !self.can_go_previous() { return; } - let playbin = self.playbin.upgrade().unwrap(); if playbin.play_queue_position() == 0 { // If there is no previous track (and endless playback and track repeat are both off), stop playback. - self.stop(); + // (interpret this as something else than what Stop does) + playbin.stop(); } else { playbin.go_to_prev_track(); } } fn pause(&self) { + let playbin = self.playbin.upgrade().unwrap(); + // If CanPause is false, attempting to call this method should have no effect. if !self.can_pause() { return; } + + // If playback is already paused, this has no effect. + if playbin.state() != crate::playbin::State::Playing { + return; + } + self.playbin.upgrade().unwrap().pause(); } @@ -262,18 +286,31 @@ impl Player { } fn stop(&self) { - // TODO: Calling Play after this should cause playback to start again from the beginning of the track. - // (not the play queue!!) - self.playbin.upgrade().unwrap().stop(); + let playbin = self.playbin.upgrade().unwrap(); + + // If playback is already stopped, this has no effect. + if playbin.state() != crate::playbin::State::Playing { + return; + } + + // Calling Play after this should cause playback to start again from the beginning of the track. + playbin.pause(); + playbin.seek(0.0); } fn play(&self) { + let playbin = self.playbin.upgrade().unwrap(); + // If CanPlay is false, attempting to call this method should have no effect. if !self.can_play() { return; } - let playbin = self.playbin.upgrade().unwrap(); + // If already playing, this has no effect. + if playbin.state() == crate::playbin::State::Playing { + return; + } + // If there is no track to play, this has no effect. if playbin.play_queue_length() == 0 { return; @@ -351,8 +388,8 @@ impl Player { } #[zbus(property)] - fn set_loop_status(&self, _loop_status: &str) { - todo!() + fn set_loop_status(&self, _loop_status: &str) -> zbus::Result<()> { + Err(zbus::Error::Unsupported) // TODO } #[zbus(property)] @@ -387,7 +424,7 @@ impl Player { #[zbus(property)] fn volume(&self) -> f64 { - 1.0 // TODO + self.playbin.upgrade().unwrap().volume() as f64 / 100.0 } #[zbus(property)] diff --git a/src/playbin/song.rs b/src/playbin/song.rs index e325a18..83cba29 100644 --- a/src/playbin/song.rs +++ b/src/playbin/song.rs @@ -25,6 +25,7 @@ pub mod ffi { pub fn audrey_playbin_song_get_album( self_: *mut AudreyPlaybinSong, ) -> *const std::ffi::c_char; + pub fn audrey_playbin_song_get_duration(self_: *mut AudreyPlaybinSong) -> i64; } } @@ -60,4 +61,8 @@ impl Song { pub fn album(&self) -> GString { unsafe { from_glib_none(ffi::audrey_playbin_song_get_album(self.to_glib_none().0)) } } + + pub fn duration(&self) -> i64 { + unsafe { ffi::audrey_playbin_song_get_duration(self.to_glib_none().0) } + } }