diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index b16e87cffbf60211823ad6b863e5e536bdcda04a..7bf91141d716fce246a06221858851b4f94a43a8 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -2052,6 +2052,7 @@ dependencies = [ "hashbrown 0.13.2", "serde", "smallstring", + "tokio", "zbus", ] diff --git a/src/rust/mpris/Cargo.toml b/src/rust/mpris/Cargo.toml index 9701120a9c15b54cdeef3bc06948e3b84e398e90..bcd98aa5818e2a15b51016ded09ebb7d9f24980a 100644 --- a/src/rust/mpris/Cargo.toml +++ b/src/rust/mpris/Cargo.toml @@ -5,11 +5,16 @@ edition.workspace = true authors.workspace = true license.workspace = true +[[bin]] +name = "mpris" +path = "src/main.rs" + [lib] doctest = false [dependencies] hashbrown.workspace = true +tokio.workspace = true serde.workspace = true zbus.workspace = true diff --git a/src/rust/mpris/src/main.rs b/src/rust/mpris/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e9858e9b21966001739fddcfe6a1051d13c2ff4 --- /dev/null +++ b/src/rust/mpris/src/main.rs @@ -0,0 +1,18 @@ +use std::future::pending; +use zbus::ConnectionBuilder; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let (main, player) = mpris::server::build("mpris"); + + let _ = ConnectionBuilder::session()? + .name("org.mpris.MediaPlayer2.mpris")? + .serve_at("/org/mpris/MediaPlayer2", main)? + .serve_at("/org/mpris/MediaPlayer2", player)? + .build() + .await?; + + // Do other things or go to wait forever + pending::<()>().await; + Ok(()) +} diff --git a/src/rust/mpris/src/server.rs b/src/rust/mpris/src/server.rs index 93be09338320f1f6ad13b63ad28cbc2c8da64e33..b748bd65d2ea709c4e1e82d79f639d98ae647976 100644 --- a/src/rust/mpris/src/server.rs +++ b/src/rust/mpris/src/server.rs @@ -5,6 +5,21 @@ use crate::types::*; use commons::log; use zbus::dbus_interface; +macro_rules! str { + ($str: literal) => { + String::from($str) + }; +} + +pub fn build(identity: impl ToString) -> (MediaPlayer2, MediaPlayer2Player) { + ( + MediaPlayer2 { + identity: identity.to_string(), + }, + MediaPlayer2Player {}, + ) +} + /// Should be served at "/org/mpris/MediaPlayer2" pub struct MediaPlayer2 { identity: String, @@ -44,7 +59,7 @@ impl MediaPlayer2 { /// DesktopEntry property #[dbus_interface(property, name = "DesktopEntry")] fn desktop_entry(&self) -> String { - todo!() + self.identity.clone() } /// Fullscreen property @@ -70,16 +85,15 @@ impl MediaPlayer2 { /// SupportedMimeTypes property #[dbus_interface(property, name = "SupportedMimeTypes")] fn supported_mime_types(&self) -> Vec<String> { - todo!() + vec![str!("video/mkv")] } - /// SupportedUriSchemes property. It should be `id://` and `file://` for - /// lektord. Here we support `file://` for only files in the database to - /// enable the user to search the kara folder and drop the files to play - /// them imediatly. + /// SupportedUriSchemes property. It should be `id` and `file` for lektord. + /// Here we support `file` for only files in the database to enable the user + /// to search the kara folder and drop the files to play them imediatly. #[dbus_interface(property, name = "SupportedUriSchemes")] fn supported_uri_schemes(&self) -> Vec<String> { - vec![String::from("id://"), String::from("file://")] + vec![str!("id"), str!("file")] } } @@ -136,13 +150,13 @@ impl MediaPlayer2Player { /// CanPause property #[dbus_interface(property)] fn can_pause(&self) -> bool { - todo!() + true } /// CanPlay property #[dbus_interface(property)] fn can_play(&self) -> bool { - todo!() + true } /// CanSeek property @@ -153,11 +167,11 @@ impl MediaPlayer2Player { /// LoopStatus property #[dbus_interface(property, name = "LoopStatus")] - fn loop_status(&self) -> MediaPlayerObjectPath { - todo!() + fn loop_status(&self) -> MediaPlayerLoopStatus { + MediaPlayerLoopStatus::None } #[dbus_interface(property, name = "LoopStatus")] - fn set_loop_status(&self, loop_status: MediaPlayerObjectPath) { + fn set_loop_status(&self, loop_status: MediaPlayerLoopStatus) { todo!("handle loop status {loop_status:?}") } @@ -171,7 +185,7 @@ impl MediaPlayer2Player { /// Shuffle property #[dbus_interface(property, name = "Shuffle")] fn shuffle(&self) -> bool { - todo!() + false } #[dbus_interface(property, name = "Shuffle")] fn set_shuffle(&self, shuffle: bool) { @@ -181,7 +195,7 @@ impl MediaPlayer2Player { /// Volume property #[dbus_interface(property, name = "Volume")] fn volume(&self) -> f64 { - todo!() + 100.0 } #[dbus_interface(property, name = "Volume")] fn set_volume(&self, volume: f64) { @@ -191,13 +205,13 @@ impl MediaPlayer2Player { /// PlaybackStatus property #[dbus_interface(property, name = "PlaybackStatus")] fn playback_status(&self) -> MediaPlayerPlaybackStatus { - todo!() + MediaPlayerPlaybackStatus::Stopped } /// Position property #[dbus_interface(property, name = "Position")] fn position(&self) -> TimeMicroSec { - todo!() + 0.into() } /// Metadata property. If there is a current kara playing, there must be at @@ -205,6 +219,6 @@ impl MediaPlayer2Player { /// the current kara id. #[dbus_interface(property, name = "Metadata")] fn metadata(&self) -> MediaPlayerMetadata { - todo!() + MediaPlayerMetadata::from_iter([]) } } diff --git a/src/rust/mpris/src/types.rs b/src/rust/mpris/src/types.rs index 7e017d11cf85d9da04c60a4ddb08379d7cd60f69..d89d6e11fa74940cbac76eaab65a9380d02a51ed 100644 --- a/src/rust/mpris/src/types.rs +++ b/src/rust/mpris/src/types.rs @@ -52,6 +52,12 @@ pub enum MediaPlayerObjectPath { // Implementations +impl FromIterator<(String, String)> for MediaPlayerMetadata { + fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self { + Self(iter.into_iter().collect()) + } +} + impl From<i64> for TimeMicroSec { fn from(value: i64) -> Self { Self(value) @@ -158,6 +164,6 @@ impl From<MediaPlayerMetadata> for ZValue<'_> { dict.append(key.into(), value.into()) .expect("invalid entry found") } - todo!() + dict.into() } }