mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
player: Implement MPRIS
This commit is contained in:
parent
c378305465
commit
31144dff46
6 changed files with 213 additions and 67 deletions
|
|
@ -3,13 +3,19 @@ use fragile::Fragile;
|
|||
use gstreamer_player::gst;
|
||||
use gtk::{
|
||||
gio,
|
||||
glib::{self, Properties},
|
||||
glib::{self, clone, Properties},
|
||||
prelude::*,
|
||||
subclass::prelude::*,
|
||||
};
|
||||
use std::cell::{Cell, OnceCell};
|
||||
use mpris_player::{MprisPlayer, PlaybackStatus};
|
||||
use std::{
|
||||
cell::{Cell, OnceCell},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
mod imp {
|
||||
use mpris_player::Metadata;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Properties, Debug, Default)]
|
||||
|
|
@ -31,6 +37,8 @@ mod imp {
|
|||
pub position: Cell<f64>,
|
||||
#[property(get, construct_only)]
|
||||
pub player: OnceCell<gstreamer_player::Player>,
|
||||
|
||||
pub mpris: OnceCell<Arc<MprisPlayer>>,
|
||||
}
|
||||
|
||||
impl MusicusPlayer {
|
||||
|
|
@ -39,21 +47,28 @@ mod imp {
|
|||
|
||||
if let Some(item) = playlist.item(index) {
|
||||
if let Some(old_item) = playlist.item(self.current_index.get()) {
|
||||
old_item.downcast::<PlaylistItem>()
|
||||
old_item
|
||||
.downcast::<PlaylistItem>()
|
||||
.unwrap()
|
||||
.set_is_playing(false);
|
||||
}
|
||||
|
||||
|
||||
let item = item.downcast::<PlaylistItem>().unwrap();
|
||||
self.mpris.get().unwrap().set_metadata(Metadata {
|
||||
artist: Some(vec![item.make_title()]),
|
||||
title: item.make_subtitle(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let uri = glib::filename_to_uri(&item.path(), None)
|
||||
.expect("track path should be parsable as an URI");
|
||||
|
||||
.expect("track path should be parsable as an URI");
|
||||
|
||||
let player = self.player.get().unwrap();
|
||||
player.set_uri(Some(&uri));
|
||||
if self.playing.get() {
|
||||
player.play();
|
||||
}
|
||||
|
||||
|
||||
self.current_index.set(index);
|
||||
item.set_is_playing(true);
|
||||
}
|
||||
|
|
@ -80,6 +95,29 @@ mod imp {
|
|||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let mpris = MprisPlayer::new(
|
||||
"de.johrpan.musicus".to_string(),
|
||||
"Musicus".to_string(),
|
||||
"de.johrpan.musicus.desktop".to_string(),
|
||||
);
|
||||
|
||||
mpris.set_can_play(true);
|
||||
mpris.set_can_pause(true);
|
||||
mpris.set_can_go_previous(true);
|
||||
mpris.set_can_go_next(true);
|
||||
mpris.set_can_seek(false);
|
||||
mpris.set_can_raise(false);
|
||||
mpris.set_can_set_fullscreen(false);
|
||||
|
||||
let obj = self.obj();
|
||||
mpris.connect_play(clone!(@weak obj => move || obj.play()));
|
||||
mpris.connect_pause(clone!(@weak obj => move || obj.pause()));
|
||||
mpris.connect_play_pause(clone!(@weak obj => move || obj.play_pause()));
|
||||
mpris.connect_previous(clone!(@weak obj => move || obj.previous()));
|
||||
mpris.connect_next(clone!(@weak obj => move || obj.next()));
|
||||
|
||||
self.mpris.set(mpris).expect("mpris should not be set");
|
||||
|
||||
let player = self.player.get().unwrap();
|
||||
|
||||
let mut config = player.config();
|
||||
|
|
@ -174,14 +212,24 @@ impl MusicusPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn play_pause(&self) {
|
||||
if self.playing() {
|
||||
self.pause();
|
||||
} else {
|
||||
self.play();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(&self) {
|
||||
self.player().play();
|
||||
self.set_playing(true);
|
||||
self.imp().mpris.get().unwrap().set_playback_status(PlaybackStatus::Playing);
|
||||
}
|
||||
|
||||
pub fn pause(&self) {
|
||||
self.player().pause();
|
||||
self.set_playing(false);
|
||||
self.imp().mpris.get().unwrap().set_playback_status(PlaybackStatus::Paused);
|
||||
}
|
||||
|
||||
pub fn current_item(&self) -> Option<PlaylistItem> {
|
||||
|
|
|
|||
|
|
@ -40,17 +40,10 @@ mod imp {
|
|||
impl PlayerBar {
|
||||
fn update(&self) {
|
||||
if let Some(item) = self.player.borrow().current_item() {
|
||||
let mut title = item.title();
|
||||
self.title_label.set_label(&item.make_title());
|
||||
|
||||
if let Some(part_title) = item.part_title() {
|
||||
title.push_str(": ");
|
||||
title.push_str(&part_title);
|
||||
}
|
||||
|
||||
self.title_label.set_label(&title);
|
||||
|
||||
if let Some(performances) = item.performers() {
|
||||
self.subtitle_label.set_label(&performances);
|
||||
if let Some(subtitle) = item.make_subtitle() {
|
||||
self.subtitle_label.set_label(&subtitle);
|
||||
self.subtitle_label.set_visible(true);
|
||||
} else {
|
||||
self.subtitle_label.set_visible(false);
|
||||
|
|
@ -179,12 +172,7 @@ impl PlayerBar {
|
|||
|
||||
#[template_callback]
|
||||
fn play_pause(&self, _: >k::Button) {
|
||||
let player = self.player();
|
||||
if player.playing() {
|
||||
player.pause();
|
||||
} else {
|
||||
player.play();
|
||||
}
|
||||
self.player().play_pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,4 +59,19 @@ impl PlaylistItem {
|
|||
.property("path", path.as_ref())
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn make_title(&self) -> String {
|
||||
let mut title = self.title();
|
||||
|
||||
if let Some(part_title) = self.part_title() {
|
||||
title.push_str(": ");
|
||||
title.push_str(&part_title);
|
||||
}
|
||||
|
||||
title
|
||||
}
|
||||
|
||||
pub fn make_subtitle(&self) -> Option<String> {
|
||||
self.performers()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue