// Copyright (c) 2022 Marceline Cramer // SPDX-License-Identifier: AGPL-3.0-or-later use canary_magpie::client::MagpieClient; use canary_magpie::protocol::{CreatePanel, MagpieServerMsg}; use canary_music_player::*; pub mod mpris; use mpris::*; pub struct Metadata { pub album: AlbumInfo, pub track: TrackInfo, } impl<'a> From<&MetadataMap<'a>> for Metadata { fn from(map: &MetadataMap<'a>) -> Self { let album = AlbumInfo { title: map .get("xesam:album") .and_then(|v| TryFrom::try_from(v).ok()), artists: map .get("xesam:albumArtist") .cloned() .and_then(|v| TryFrom::try_from(v).ok()) .unwrap_or(Vec::new()), }; let track = TrackInfo { title: map .get("xesam:title") .and_then(|v| TryFrom::try_from(v).ok()), artists: map .get("xesam:artist") .cloned() .and_then(|v| TryFrom::try_from(v).ok()) .unwrap_or(Vec::new()), track_number: map .get("xesam:trackNumber") .and_then(|v| TryFrom::try_from(v).ok()), }; Self { album, track } } } /*impl MetadataTracker { pub fn new(magpie: &mut MagpieClient, metadata: &MetadataMap) -> Self { let new: Self = metadata.into(); magpie.send_json_message(0, &InMsg::AlbumChanged(new.album.clone())); magpie.send_json_message(0, &InMsg::TrackChanged(new.track.clone())); magpie.send_json_message( 0, &InMsg::ProgressChanged(ProgressChanged { position: 0.0, length: metadata.length().map(|l| l.as_secs_f32()), }), ); new } pub fn update(&mut self, messenger: &mut MagpieClient, metadata: &MetadataMap) { let new: Self = metadata.into(); if self.album != new.album { messenger.send_json_message(0, &InMsg::AlbumChanged(new.album.clone())); } if self.track != new.track { messenger.send_json_message(0, &InMsg::TrackChanged(new.track.clone())); messenger.send_json_message( 0, &InMsg::ProgressChanged(ProgressChanged { position: 0.0, length: metadata.length().map(|l| l.as_secs_f32()), }), ); } *self = new; } }*/ fn main() { let args: Vec = std::env::args().collect(); let module_path = args .get(1) .expect("Please pass a path to a Canary script!") .to_owned(); let mut magpie = MagpieClient::new().unwrap(); let result: Result<(), Box> = smol::block_on(async { let dbus = zbus::Connection::session().await?; let player = find_player(&dbus).await?.unwrap(); use futures_util::StreamExt; let mut playback_status = player.receive_playback_status_changed().await.fuse(); let mut metadata = player.receive_metadata_changed().await.fuse(); loop { futures_util::select! { status = playback_status.next() => { let status = match status { Some(v) => v, None => break, }; println!("Status: {}", status.get().await?); } metadata = metadata.next() => { let metadata = match metadata { Some(v) => v, None => break, }; println!("Metadata: {:#?}", metadata.get().await?); } }; } let protocol = "tebibyte-media.desktop.music-player-controller".to_string(); let script = std::path::PathBuf::from(&module_path); let msg = CreatePanel { id: 0, protocol, script, }; let msg = MagpieServerMsg::CreatePanel(msg); magpie.messenger.send(&msg).unwrap(); std::future::pending::<()>().await; Ok(()) }); if let Err(err) = result { eprintln!("Music player error: {:?}", err); } /*let mut first_loop = true; let mut connected = false; loop { if !first_loop { let wait = std::time::Duration::from_secs(1); std::thread::sleep(wait); } first_loop = false; if connected { println!("Disconnected from MPRIS"); let msg = InMsg::Disconnected; magpie.send_json_message(0, &msg); connected = false; } println!("Connecting to MPRIS..."); let player = match player_finder.find_active() { Ok(player) => player, Err(err) => { eprintln!("Couldn't find player: {:?}", err); continue; } }; println!( "Connected to \"{}\" ({})", player.identity(), player.bus_name() ); connected = true; magpie.send_json_message(0, &InMsg::Connected); let metadata = player.get_metadata().unwrap(); let mut metadata_tracker = MetadataTracker::new(&mut magpie, &metadata); let mut events = match player.events() { Ok(events) => events, Err(err) => { eprintln!("Player events D-Bus error: {:?}", err); continue; } }; loop { let event = match events.next() { None => break, Some(Ok(e)) => e, Some(Err(err)) => { eprintln!("D-Bus error while reading player events: {:?}", err); continue; } }; use mpris::Event::*; let in_msg = match event { Playing => Some(InMsg::PlaybackStatusChanged(PlaybackStatus::Playing)), Paused => Some(InMsg::PlaybackStatusChanged(PlaybackStatus::Paused)), Stopped => Some(InMsg::PlaybackStatusChanged(PlaybackStatus::Stopped)), LoopingChanged(status) => { use mpris::LoopStatus::*; let status = match status { None => LoopStatus::None, Track => LoopStatus::Track, Playlist => LoopStatus::Playlist, }; Some(InMsg::LoopingChanged(status)) } ShuffleToggled(shuffle) => Some(InMsg::ShuffleChanged { shuffle }), VolumeChanged(volume) => Some(InMsg::VolumeChanged { volume: volume as f32, }), PlayerShutDown => None, TrackChanged(ref metadata) => { metadata_tracker.update(&mut magpie, metadata); None } _ => { eprintln!("Unhandled MPRIS message: {:?}", event); None } }; if let Some(msg) = in_msg { magpie.send_json_message(0, &msg); } } }*/ }