docs: add more internal docs for mpris

This commit is contained in:
Tal 2024-10-24 19:04:14 +02:00
parent ab288ee0d4
commit e7ac0c9214
2 changed files with 50 additions and 33 deletions

View File

@ -20,7 +20,7 @@ use tokio::{
}; };
#[cfg(feature = "mpris")] #[cfg(feature = "mpris")]
use mpris_server::{PlaybackStatus, PlayerInterface}; use mpris_server::{PlaybackStatus, PlayerInterface, Property};
use crate::{ use crate::{
play::PersistentVolume, play::PersistentVolume,
@ -391,9 +391,7 @@ impl Player {
#[cfg(feature = "mpris")] #[cfg(feature = "mpris")]
mpris mpris
.changed(vec![mpris_server::Property::Volume( .changed(vec![Property::Volume(player.sink.volume().into())])
player.sink.volume().into(),
)])
.await?; .await?;
} }
// This basically just continues, but more importantly, it'll re-evaluate // This basically just continues, but more importantly, it'll re-evaluate
@ -407,10 +405,8 @@ impl Player {
#[cfg(feature = "mpris")] #[cfg(feature = "mpris")]
mpris mpris
.changed(vec![ .changed(vec![
mpris_server::Property::Metadata(mpris.player().metadata().await?), Property::Metadata(mpris.player().metadata().await?),
mpris_server::Property::PlaybackStatus( Property::PlaybackStatus(mpris.player().playback_status().await?),
mpris.player().playback_status().await?,
),
]) ])
.await?; .await?;

View File

@ -1,9 +1,11 @@
//! Contains the code for the MPRIS server & other helper functions.
use std::sync::Arc; use std::sync::Arc;
use mpris_server::{ use mpris_server::{
zbus::{self, fdo, Result}, zbus::{self, fdo, Result},
LoopStatus, Metadata, PlaybackRate, PlaybackStatus, PlayerInterface, RootInterface, Time, LoopStatus, Metadata, PlaybackRate, PlaybackStatus, PlayerInterface, Property, RootInterface,
TrackId, Volume, Time, TrackId, Volume,
}; };
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
@ -13,7 +15,11 @@ const ERROR: fdo::Error = fdo::Error::Failed(String::new());
/// The actual MPRIS player. /// The actual MPRIS player.
pub struct Player { pub struct Player {
/// A reference to the [`super::Player`] itself.
pub player: Arc<super::Player>, pub player: Arc<super::Player>,
/// The audio server sender, which is used to communicate with
/// the audio sender for skips and a few other inputs.
pub sender: Sender<Messages>, pub sender: Sender<Messages>,
} }
@ -23,7 +29,10 @@ impl RootInterface for Player {
} }
async fn quit(&self) -> fdo::Result<()> { async fn quit(&self) -> fdo::Result<()> {
self.sender.send(Messages::Quit).await.map_err(|_| ERROR) self.sender
.send(Messages::Quit)
.await
.map_err(|_error| ERROR)
} }
async fn can_quit(&self) -> fdo::Result<bool> { async fn can_quit(&self) -> fdo::Result<bool> {
@ -51,25 +60,28 @@ impl RootInterface for Player {
} }
async fn identity(&self) -> fdo::Result<String> { async fn identity(&self) -> fdo::Result<String> {
Ok("lowfi".to_string()) Ok("lowfi".to_owned())
} }
async fn desktop_entry(&self) -> fdo::Result<String> { async fn desktop_entry(&self) -> fdo::Result<String> {
Ok("dev.talwat.lowfi".to_string()) Ok("dev.talwat.lowfi".to_owned())
} }
async fn supported_uri_schemes(&self) -> fdo::Result<Vec<String>> { async fn supported_uri_schemes(&self) -> fdo::Result<Vec<String>> {
Ok(vec!["https".to_string()]) Ok(vec!["https".to_owned()])
} }
async fn supported_mime_types(&self) -> fdo::Result<Vec<String>> { async fn supported_mime_types(&self) -> fdo::Result<Vec<String>> {
Ok(vec!["audio/mpeg".to_string()]) Ok(vec!["audio/mpeg".to_owned()])
} }
} }
impl PlayerInterface for Player { impl PlayerInterface for Player {
async fn next(&self) -> fdo::Result<()> { async fn next(&self) -> fdo::Result<()> {
self.sender.send(Messages::Next).await.map_err(|_| ERROR) self.sender
.send(Messages::Next)
.await
.map_err(|_error| ERROR)
} }
async fn previous(&self) -> fdo::Result<()> { async fn previous(&self) -> fdo::Result<()> {
@ -77,14 +89,17 @@ impl PlayerInterface for Player {
} }
async fn pause(&self) -> fdo::Result<()> { async fn pause(&self) -> fdo::Result<()> {
self.sender.send(Messages::Pause).await.map_err(|_| ERROR) self.sender
.send(Messages::Pause)
.await
.map_err(|_error| ERROR)
} }
async fn play_pause(&self) -> fdo::Result<()> { async fn play_pause(&self) -> fdo::Result<()> {
self.sender self.sender
.send(Messages::PlayPause) .send(Messages::PlayPause)
.await .await
.map_err(|_| ERROR) .map_err(|_error| ERROR)
} }
async fn stop(&self) -> fdo::Result<()> { async fn stop(&self) -> fdo::Result<()> {
@ -92,7 +107,10 @@ impl PlayerInterface for Player {
} }
async fn play(&self) -> fdo::Result<()> { async fn play(&self) -> fdo::Result<()> {
self.sender.send(Messages::Play).await.map_err(|_| ERROR) self.sender
.send(Messages::Play)
.await
.map_err(|_error| ERROR)
} }
async fn seek(&self, _offset: Time) -> fdo::Result<()> { async fn seek(&self, _offset: Time) -> fdo::Result<()> {
@ -143,20 +161,22 @@ impl PlayerInterface for Player {
} }
async fn metadata(&self) -> fdo::Result<Metadata> { async fn metadata(&self) -> fdo::Result<Metadata> {
let metadata = match self.player.current.load().as_ref() { let metadata = self
Some(track) => { .player
.current
.load()
.as_ref()
.map_or_else(Metadata::new, |track| {
let mut metadata = Metadata::builder().title(track.name.clone()).build(); let mut metadata = Metadata::builder().title(track.name.clone()).build();
metadata.set_length( metadata.set_length(
track track
.duration .duration
.and_then(|x| Some(Time::from_micros(x.as_micros() as i64))), .map(|x| Time::from_micros(x.as_micros() as i64)),
); );
metadata metadata
} });
None => Metadata::new(),
};
Ok(metadata) Ok(metadata)
} }
@ -178,11 +198,11 @@ impl PlayerInterface for Player {
} }
async fn minimum_rate(&self) -> fdo::Result<PlaybackRate> { async fn minimum_rate(&self) -> fdo::Result<PlaybackRate> {
Ok(0.2) Ok(0.2f64)
} }
async fn maximum_rate(&self) -> fdo::Result<PlaybackRate> { async fn maximum_rate(&self) -> fdo::Result<PlaybackRate> {
Ok(3.0) Ok(3.0f64)
} }
async fn can_go_next(&self) -> fdo::Result<bool> { async fn can_go_next(&self) -> fdo::Result<bool> {
@ -213,6 +233,7 @@ impl PlayerInterface for Player {
/// A struct which contains the MPRIS [Server], and has some helper functions /// A struct which contains the MPRIS [Server], and has some helper functions
/// to make it easier to work with. /// to make it easier to work with.
pub struct Server { pub struct Server {
/// The inner MPRIS server.
inner: mpris_server::Server<Player>, inner: mpris_server::Server<Player>,
} }
@ -220,7 +241,7 @@ impl Server {
/// Shorthand to emit a `PropertiesChanged` signal, like when pausing/unpausing. /// Shorthand to emit a `PropertiesChanged` signal, like when pausing/unpausing.
pub async fn changed( pub async fn changed(
&self, &self,
properties: impl IntoIterator<Item = mpris_server::Property>, properties: impl IntoIterator<Item = mpris_server::Property> + Send + Sync,
) -> eyre::Result<()> { ) -> eyre::Result<()> {
self.inner.properties_changed(properties).await?; self.inner.properties_changed(properties).await?;
@ -230,7 +251,7 @@ impl Server {
/// Shorthand to emit a `PropertiesChanged` signal, specifically about playback. /// Shorthand to emit a `PropertiesChanged` signal, specifically about playback.
pub async fn playback(&self, new: PlaybackStatus) -> zbus::Result<()> { pub async fn playback(&self, new: PlaybackStatus) -> zbus::Result<()> {
self.inner self.inner
.properties_changed(vec![mpris_server::Property::PlaybackStatus(new)]) .properties_changed(vec![Property::PlaybackStatus(new)])
.await .await
} }
@ -239,11 +260,11 @@ impl Server {
self.inner.imp() self.inner.imp()
} }
/// Creates a new MPRIS server.
pub async fn new(player: Arc<super::Player>, sender: Sender<Messages>) -> eyre::Result<Self> { pub async fn new(player: Arc<super::Player>, sender: Sender<Messages>) -> eyre::Result<Self> {
let server = let server = mpris_server::Server::new("lowfi", Player { player, sender })
mpris_server::Server::new("lowfi", crate::player::mpris::Player { player, sender }) .await
.await .unwrap();
.unwrap();
Ok(Self { inner: server }) Ok(Self { inner: server })
} }