backend: Only require Dbus on Linux

This commit is contained in:
Elias Projahn 2021-02-15 12:38:17 +01:00
parent e357ab1c1f
commit 266335dfc5
4 changed files with 88 additions and 64 deletions

View file

@ -12,9 +12,10 @@ glib = "0.10.3"
gstreamer = "0.16.4" gstreamer = "0.16.4"
gstreamer-player = "0.16.3" gstreamer-player = "0.16.3"
log = "0.4.14" log = "0.4.14"
mpris-player = "0.6.0"
musicus_client = { version = "0.1.0", path = "../client" } musicus_client = { version = "0.1.0", path = "../client" }
musicus_database = { version = "0.1.0", path = "../database" } musicus_database = { version = "0.1.0", path = "../database" }
secret-service = "2.0.1"
thiserror = "1.0.23" thiserror = "1.0.23"
[target.'cfg(target_os = "linux")'.dependencies]
mpris-player = "0.6.0"
secret-service = "2.0.1"

View file

@ -7,6 +7,7 @@ pub enum Error {
#[error(transparent)] #[error(transparent)]
DatabaseError(#[from] musicus_database::Error), DatabaseError(#[from] musicus_database::Error),
#[cfg(target_os = "linux")]
#[error("An error happened using the SecretService.")] #[error("An error happened using the SecretService.")]
SecretServiceError(#[from] secret_service::Error), SecretServiceError(#[from] secret_service::Error),

View file

@ -20,6 +20,7 @@ pub use library::*;
pub mod player; pub mod player;
pub use player::*; pub use player::*;
#[cfg(all(feature = "dbus"))]
mod secure; mod secure;
/// General states the application can be in. /// General states the application can be in.
@ -97,6 +98,7 @@ impl Backend {
} }
} }
#[cfg(all(feature = "dbus"))]
match Self::load_login_data().await { match Self::load_login_data().await {
Ok(Some(data)) => self.client.set_login_data(Some(data)), Ok(Some(data)) => self.client.set_login_data(Some(data)),
Err(err) => warn!("The login data could not be loaded from SecretService. It will not \ Err(err) => warn!("The login data could not be loaded from SecretService. It will not \
@ -130,6 +132,7 @@ impl Backend {
/// Set the user credentials to use. /// Set the user credentials to use.
pub async fn set_login_data(&self, data: Option<LoginData>) { pub async fn set_login_data(&self, data: Option<LoginData>) {
#[cfg(all(feature = "dbus"))]
if let Some(data) = &data { if let Some(data) = &data {
if let Err(err) = Self::store_login_data(data.clone()).await { if let Err(err) = Self::store_login_data(data.clone()).await {
warn!("An error happened while trying to store the login data using SecretService. \ warn!("An error happened while trying to store the login data using SecretService. \

View file

@ -1,5 +1,4 @@
use crate::{Error, Result}; use crate::{Error, Result};
use mpris_player::{Metadata, MprisPlayer, PlaybackStatus};
use musicus_database::TrackSet; use musicus_database::TrackSet;
use glib::clone; use glib::clone;
use gstreamer_player::prelude::*; use gstreamer_player::prelude::*;
@ -8,6 +7,9 @@ use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
#[cfg(target_os = "linux")]
use mpris_player::{Metadata, MprisPlayer, PlaybackStatus};
#[derive(Clone)] #[derive(Clone)]
pub struct PlaylistItem { pub struct PlaylistItem {
pub track_set: TrackSet, pub track_set: TrackSet,
@ -17,7 +19,6 @@ pub struct PlaylistItem {
pub struct Player { pub struct Player {
music_library_path: PathBuf, music_library_path: PathBuf,
player: gstreamer_player::Player, player: gstreamer_player::Player,
mpris: Arc<MprisPlayer>,
playlist: RefCell<Vec<PlaylistItem>>, playlist: RefCell<Vec<PlaylistItem>>,
current_item: Cell<Option<usize>>, current_item: Cell<Option<usize>>,
current_track: Cell<Option<usize>>, current_track: Cell<Option<usize>>,
@ -28,6 +29,9 @@ pub struct Player {
playing_cbs: RefCell<Vec<Box<dyn Fn(bool)>>>, playing_cbs: RefCell<Vec<Box<dyn Fn(bool)>>>,
position_cbs: RefCell<Vec<Box<dyn Fn(u64)>>>, position_cbs: RefCell<Vec<Box<dyn Fn(u64)>>>,
raise_cb: RefCell<Option<Box<dyn Fn()>>>, raise_cb: RefCell<Option<Box<dyn Fn()>>>,
#[cfg(target_os = "linux")]
mpris: Arc<MprisPlayer>,
} }
impl Player { impl Player {
@ -39,24 +43,9 @@ impl Player {
player.set_config(config).unwrap(); player.set_config(config).unwrap();
player.set_video_track_enabled(false); player.set_video_track_enabled(false);
let mpris = MprisPlayer::new(
"de.johrpan.musicus".to_string(),
"Musicus".to_string(),
"de.johrpan.musicus.desktop".to_string(),
);
mpris.set_can_raise(true);
mpris.set_can_play(false);
mpris.set_can_go_previous(false);
mpris.set_can_go_next(false);
mpris.set_can_seek(false);
mpris.set_can_set_fullscreen(false);
let result = Rc::new(Self { let result = Rc::new(Self {
music_library_path, music_library_path,
player: player.clone(), player: player.clone(),
mpris,
playlist: RefCell::new(Vec::new()), playlist: RefCell::new(Vec::new()),
current_item: Cell::new(None), current_item: Cell::new(None),
current_track: Cell::new(None), current_track: Cell::new(None),
@ -67,6 +56,23 @@ impl Player {
playing_cbs: RefCell::new(Vec::new()), playing_cbs: RefCell::new(Vec::new()),
position_cbs: RefCell::new(Vec::new()), position_cbs: RefCell::new(Vec::new()),
raise_cb: RefCell::new(None), raise_cb: RefCell::new(None),
#[cfg(target_os = "linux")]
mpris: {
let mpris = MprisPlayer::new(
"de.johrpan.musicus".to_string(),
"Musicus".to_string(),
"de.johrpan.musicus.desktop".to_string(),
);
mpris.set_can_raise(true);
mpris.set_can_play(false);
mpris.set_can_go_previous(false);
mpris.set_can_go_next(false);
mpris.set_can_seek(false);
mpris.set_can_set_fullscreen(false);
mpris
},
}); });
let clone = fragile::Fragile::new(result.clone()); let clone = fragile::Fragile::new(result.clone());
@ -82,6 +88,7 @@ impl Player {
cb(false); cb(false);
} }
#[cfg(target_os = "linux")]
clone.mpris.set_playback_status(PlaybackStatus::Paused); clone.mpris.set_playback_status(PlaybackStatus::Paused);
} }
}); });
@ -100,36 +107,39 @@ impl Player {
} }
}); });
result.mpris.connect_play_pause(clone!(@weak result => move || { #[cfg(target_os = "linux")]
result.play_pause(); {
})); result.mpris.connect_play_pause(clone!(@weak result => move || {
result.mpris.connect_play(clone!(@weak result => move || {
if !result.is_playing() {
result.play_pause(); result.play_pause();
} }));
}));
result.mpris.connect_pause(clone!(@weak result => move || { result.mpris.connect_play(clone!(@weak result => move || {
if result.is_playing() { if !result.is_playing() {
result.play_pause(); result.play_pause();
} }
})); }));
result.mpris.connect_previous(clone!(@weak result => move || { result.mpris.connect_pause(clone!(@weak result => move || {
let _ = result.previous(); if result.is_playing() {
})); result.play_pause();
}
}));
result.mpris.connect_next(clone!(@weak result => move || { result.mpris.connect_previous(clone!(@weak result => move || {
let _ = result.next(); let _ = result.previous();
})); }));
result.mpris.connect_raise(clone!(@weak result => move || { result.mpris.connect_next(clone!(@weak result => move || {
let cb = result.raise_cb.borrow(); let _ = result.next();
if let Some(cb) = &*cb { }));
cb()
} result.mpris.connect_raise(clone!(@weak result => move || {
})); let cb = result.raise_cb.borrow();
if let Some(cb) = &*cb {
cb()
}
}));
}
result result
} }
@ -204,8 +214,11 @@ impl Player {
cb(true); cb(true);
} }
self.mpris.set_can_play(true); #[cfg(target_os = "linux")]
self.mpris.set_playback_status(PlaybackStatus::Playing); {
self.mpris.set_can_play(true);
self.mpris.set_playback_status(PlaybackStatus::Playing);
}
} }
Ok(()) Ok(())
@ -221,6 +234,7 @@ impl Player {
cb(false); cb(false);
} }
#[cfg(target_os = "linux")]
self.mpris.set_playback_status(PlaybackStatus::Paused); self.mpris.set_playback_status(PlaybackStatus::Paused);
} else { } else {
self.player.play(); self.player.play();
@ -230,6 +244,7 @@ impl Player {
cb(true); cb(true);
} }
#[cfg(target_os = "linux")]
self.mpris.set_playback_status(PlaybackStatus::Playing); self.mpris.set_playback_status(PlaybackStatus::Playing);
} }
} }
@ -330,26 +345,29 @@ impl Player {
cb(current_item, current_track); cb(current_item, current_track);
} }
let mut parts = Vec::<String>::new(); #[cfg(target_os = "linux")]
for part in &track.work_parts { {
parts.push(item.track_set.recording.work.parts[*part].title.clone()); let mut parts = Vec::<String>::new();
for part in &track.work_parts {
parts.push(item.track_set.recording.work.parts[*part].title.clone());
}
let mut title = item.track_set.recording.work.get_title();
if !parts.is_empty() {
title = format!("{}: {}", title, parts.join(", "));
}
let subtitle = item.track_set.recording.get_performers();
let mut metadata = Metadata::new();
metadata.artist = Some(vec![title]);
metadata.title = Some(subtitle);
self.mpris.set_metadata(metadata);
self.mpris.set_can_go_previous(self.has_previous());
self.mpris.set_can_go_next(self.has_next());
} }
let mut title = item.track_set.recording.work.get_title();
if !parts.is_empty() {
title = format!("{}: {}", title, parts.join(", "));
}
let subtitle = item.track_set.recording.get_performers();
let mut metadata = Metadata::new();
metadata.artist = Some(vec![title]);
metadata.title = Some(subtitle);
self.mpris.set_metadata(metadata);
self.mpris.set_can_go_previous(self.has_previous());
self.mpris.set_can_go_next(self.has_next());
Ok(()) Ok(())
} }
@ -386,6 +404,7 @@ impl Player {
cb(Vec::new()); cb(Vec::new());
} }
#[cfg(target_os = "linux")]
self.mpris.set_can_play(false); self.mpris.set_can_play(false);
} }
} }