canary-rs/apps/music-player/src/main.rs

235 lines
7.2 KiB
Rust
Raw Normal View History

// 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::*;
2022-09-24 18:54:55 +00:00
2022-11-20 04:42:16 +00:00
pub mod mpris;
use mpris::*;
pub struct Metadata {
pub album: AlbumInfo,
pub track: TrackInfo,
}
2022-11-20 04:42:16 +00:00
impl<'a> From<&MetadataMap<'a>> for Metadata {
fn from(map: &MetadataMap<'a>) -> Self {
let album = AlbumInfo {
2022-11-20 04:42:16 +00:00
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 {
2022-11-20 04:42:16 +00:00
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()),
};
2022-09-24 18:54:55 +00:00
Self { album, track }
}
2022-09-24 18:54:55 +00:00
}
2022-11-20 04:42:16 +00:00
/*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
2022-09-24 18:54:55 +00:00
}
2022-11-20 04:42:16 +00:00
pub fn update(&mut self, messenger: &mut MagpieClient, metadata: &MetadataMap) {
let new: Self = metadata.into();
2022-09-24 18:54:55 +00:00
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()),
}),
);
}
2022-09-24 18:54:55 +00:00
*self = new;
2022-09-24 18:54:55 +00:00
}
2022-11-20 04:42:16 +00:00
}*/
2022-09-24 18:54:55 +00:00
fn main() {
let args: Vec<String> = std::env::args().collect();
let module_path = args
.get(1)
.expect("Please pass a path to a Canary script!")
.to_owned();
2022-10-30 05:26:02 +00:00
let mut magpie = MagpieClient::new().unwrap();
2022-09-24 18:54:55 +00:00
2022-11-20 04:42:16 +00:00
let result: Result<(), Box<dyn std::error::Error>> = smol::block_on(async {
let dbus = zbus::Connection::session().await?;
let player = find_player(&dbus).await?.unwrap();
2022-11-20 05:57:33 +00:00
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?);
}
};
}
2022-11-20 04:42:16 +00:00
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;
2022-10-30 05:26:02 +00:00
loop {
if !first_loop {
let wait = std::time::Duration::from_secs(1);
std::thread::sleep(wait);
}
first_loop = false;
2022-10-30 05:26:02 +00:00
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,
2022-10-30 05:26:02 +00:00
Err(err) => {
eprintln!("Couldn't find player: {:?}", err);
continue;
2022-09-24 18:54:55 +00:00
}
2022-10-30 05:26:02 +00:00
};
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,
};
2022-10-30 05:26:02 +00:00
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);
}
}
2022-11-20 04:42:16 +00:00
}*/
2022-09-24 18:54:55 +00:00
}