Compare commits
5 commits
940254b4fd
...
19528beb22
Author | SHA1 | Date | |
---|---|---|---|
19528beb22 | |||
d873d03973 | |||
6272c2ce07 | |||
519424d42f | |||
286c0e552d |
7 changed files with 214 additions and 52 deletions
|
@ -25,7 +25,6 @@ mod imp {
|
||||||
window.present();
|
window.present();
|
||||||
|
|
||||||
glib::spawn_future_local(async move {
|
glib::spawn_future_local(async move {
|
||||||
// run this in glib's main loop
|
|
||||||
let conn = zbus::connection::Builder::session()
|
let conn = zbus::connection::Builder::session()
|
||||||
.expect("could not connect to the session bus")
|
.expect("could not connect to the session bus")
|
||||||
.internal_executor(false)
|
.internal_executor(false)
|
||||||
|
@ -33,6 +32,17 @@ mod imp {
|
||||||
.await
|
.await
|
||||||
.expect("could not build connection to the session bus");
|
.expect("could not build connection to the session bus");
|
||||||
|
|
||||||
|
// run this in glib's main loop
|
||||||
|
glib::spawn_future_local(glib::clone!(
|
||||||
|
#[strong]
|
||||||
|
conn,
|
||||||
|
async move {
|
||||||
|
loop {
|
||||||
|
conn.executor().tick().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
crate::Mpris::setup(conn.object_server(), &window)
|
crate::Mpris::setup(conn.object_server(), &window)
|
||||||
.await
|
.await
|
||||||
.expect("could not serve mpris");
|
.expect("could not serve mpris");
|
||||||
|
@ -49,10 +59,6 @@ mod imp {
|
||||||
conn.request_name("org.mpris.MediaPlayer2.audrey")
|
conn.request_name("org.mpris.MediaPlayer2.audrey")
|
||||||
.await
|
.await
|
||||||
.expect("could not register name in session bus");
|
.expect("could not register name in session bus");
|
||||||
|
|
||||||
loop {
|
|
||||||
conn.executor().tick().await;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(win) => win.present(),
|
Some(win) => win.present(),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/*
|
||||||
[DBus (name = "org.mpris.MediaPlayer2.Player")]
|
[DBus (name = "org.mpris.MediaPlayer2.Player")]
|
||||||
class Audrey.MprisPlayer : Object {
|
class Audrey.MprisPlayer : Object {
|
||||||
internal signal void on_next ();
|
internal signal void on_next ();
|
||||||
|
@ -22,9 +23,9 @@ class Audrey.MprisPlayer : Object {
|
||||||
public signal void seeked (int64 position);
|
public signal void seeked (int64 position);
|
||||||
|
|
||||||
public string playback_status { owned get; internal set; default = "Stopped"; }
|
public string playback_status { owned get; internal set; default = "Stopped"; }
|
||||||
public string loop_status { owned get; /*set;*/ default = "None"; }
|
public string loop_status { owned get; set; default = "None"; }
|
||||||
public double rate { get; /*set*/ default = 1.0; }
|
public double rate { get; set default = 1.0; }
|
||||||
public bool shuffle { get; /*set*/ default = false; }
|
public bool shuffle { get; set default = false; }
|
||||||
public HashTable<string, Variant> metadata { owned get; private set; default = new HashTable<string, Variant> (null, null); }
|
public HashTable<string, Variant> metadata { owned get; private set; default = new HashTable<string, Variant> (null, null); }
|
||||||
public double volume { get; set; default = 1.0; }
|
public double volume { get; set; default = 1.0; }
|
||||||
[CCode (notify = false)]
|
[CCode (notify = false)]
|
||||||
|
@ -219,3 +220,4 @@ class Audrey.MprisPlayer : Object {
|
||||||
debug ("destroying mpris player");
|
debug ("destroying mpris player");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,11 +1,45 @@
|
||||||
use glib::SendWeakRef;
|
use glib::SendWeakRef;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
use std::collections::HashMap;
|
||||||
use zbus::object_server::SignalEmitter;
|
use zbus::object_server::SignalEmitter;
|
||||||
use zbus::zvariant::{ObjectPath, Value};
|
use zbus::zvariant::{ObjectPath, OwnedObjectPath, Value};
|
||||||
|
|
||||||
|
const MICROSECONDS: f64 = 1e6; // in a second
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct MetadataMap {
|
||||||
|
pub track_id: Option<OwnedObjectPath>,
|
||||||
|
// rest: TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetadataMap {
|
||||||
|
fn from_playbin_song(song: Option<&crate::playbin::Song>) -> Self {
|
||||||
|
song.map(|song| MetadataMap {
|
||||||
|
// FIXME: see if there's a better way to do this lol
|
||||||
|
track_id: Some({
|
||||||
|
let song_object_intptr =
|
||||||
|
glib::translate::ToGlibPtr::<*const _>::to_glib_none(song).0 as usize;
|
||||||
|
format!("/eu/callcc/audrey/TrackId/{song_object_intptr:x}")
|
||||||
|
.try_into()
|
||||||
|
.unwrap()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.unwrap_or_else(Default::default)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_hash_map(&self) -> HashMap<&'static str, Value> {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
if let Some(track_id) = &self.track_id {
|
||||||
|
map.insert("mpris:trackid", Value::new(track_id.as_ref()));
|
||||||
|
}
|
||||||
|
map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
playbin: SendWeakRef<crate::Playbin>,
|
playbin: SendWeakRef<crate::Playbin>,
|
||||||
metadata: Vec<(String, String)>,
|
metadata: MetadataMap,
|
||||||
|
volume: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
|
@ -17,12 +51,13 @@ impl Player {
|
||||||
|
|
||||||
let player = Self {
|
let player = Self {
|
||||||
playbin: playbin.downgrade().into(),
|
playbin: playbin.downgrade().into(),
|
||||||
metadata: Default::default(),
|
metadata: MetadataMap::from_playbin_song(None),
|
||||||
|
volume: (playbin.volume() as f64) / 100.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
object_server.at("/org/mpris/MediaPlayer2", player).await?;
|
object_server.at("/org/mpris/MediaPlayer2", player).await?;
|
||||||
|
|
||||||
let player = object_server
|
let player_ref = object_server
|
||||||
.interface::<_, Self>("/org/mpris/MediaPlayer2")
|
.interface::<_, Self>("/org/mpris/MediaPlayer2")
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -31,10 +66,40 @@ impl Player {
|
||||||
false,
|
false,
|
||||||
glib::closure_local!(
|
glib::closure_local!(
|
||||||
#[strong]
|
#[strong]
|
||||||
player,
|
player_ref,
|
||||||
move |_playbin: &crate::Playbin| {
|
move |_playbin: &crate::Playbin, song: &crate::playbin::Song| {
|
||||||
let _player = player.get_mut();
|
let metadata = MetadataMap::from_playbin_song(Some(song));
|
||||||
// TODO
|
|
||||||
|
let player_ref = player_ref.clone();
|
||||||
|
glib::spawn_future_local(async move {
|
||||||
|
let mut player = player_ref.get_mut().await;
|
||||||
|
player.metadata = metadata;
|
||||||
|
player
|
||||||
|
.metadata_changed(player_ref.signal_emitter())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
playbin.connect_notify_local(
|
||||||
|
Some("volume"),
|
||||||
|
glib::clone!(
|
||||||
|
#[strong]
|
||||||
|
player_ref,
|
||||||
|
move |playbin: &crate::Playbin, _| {
|
||||||
|
let playbin_volume = playbin.volume();
|
||||||
|
|
||||||
|
let player_ref = player_ref.clone();
|
||||||
|
glib::spawn_future_local(async move {
|
||||||
|
let mut player = player_ref.get_mut().await;
|
||||||
|
player.volume = (playbin_volume as f64) / 100.0;
|
||||||
|
player
|
||||||
|
.volume_changed(player_ref.signal_emitter())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -46,39 +111,122 @@ impl Player {
|
||||||
#[zbus::interface(name = "org.mpris.MediaPlayer2.Player")]
|
#[zbus::interface(name = "org.mpris.MediaPlayer2.Player")]
|
||||||
impl Player {
|
impl Player {
|
||||||
fn next(&self) {
|
fn next(&self) {
|
||||||
todo!()
|
// If CanGoNext is false, attempting to call this method should have no effect.
|
||||||
|
if !self.can_go_next() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
if playbin.play_queue_position() + 1 > playbin.play_queue_length() {
|
||||||
|
// If there is no next track (and endless playback and track repeat are both off), stop playback.
|
||||||
|
self.stop();
|
||||||
|
} else {
|
||||||
|
playbin.go_to_next_track();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn previous(&self) {
|
fn previous(&self) {
|
||||||
todo!()
|
// If CanGoPrevious is false, attempting to call this method should have no effect.
|
||||||
|
if !self.can_go_previous() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
if playbin.play_queue_position() == 0 {
|
||||||
|
// If there is no previous track (and endless playback and track repeat are both off), stop playback.
|
||||||
|
self.stop();
|
||||||
|
} else {
|
||||||
|
playbin.go_to_prev_track();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) {
|
fn pause(&self) {
|
||||||
todo!()
|
// If CanPause is false, attempting to call this method should have no effect.
|
||||||
|
if !self.can_pause() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.playbin.upgrade().unwrap().pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play_pause(&self) {
|
fn play_pause(&self) {
|
||||||
todo!()
|
// don't think this is exactly according to spec but it looks more reasonable to me
|
||||||
|
if self.playbin.upgrade().unwrap().state() == crate::playbin::State::Paused {
|
||||||
|
self.play();
|
||||||
|
} else {
|
||||||
|
self.pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
todo!()
|
// TODO: Calling Play after this should cause playback to start again from the beginning of the track.
|
||||||
|
// (not the play queue!!)
|
||||||
|
self.playbin.upgrade().unwrap().stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play(&self) {
|
fn play(&self) {
|
||||||
todo!()
|
// If CanPlay is false, attempting to call this method should have no effect.
|
||||||
|
if !self.can_play() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
// If there is no track to play, this has no effect.
|
||||||
|
if playbin.play_queue_length() == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playbin.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seek(&self, _offset: i64) {
|
fn seek(&self, offset: i64) {
|
||||||
todo!()
|
// If the CanSeek property is false, this has no effect.
|
||||||
|
if !self.can_seek() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
// Seeks forward in the current track by the specified number of microseconds.
|
||||||
|
let mut new_position = (playbin.position() * MICROSECONDS) as i64 + offset;
|
||||||
|
|
||||||
|
// A negative value seeks back. If this would mean seeking back further than the start of the track, the position is set to 0.
|
||||||
|
if new_position < 0 {
|
||||||
|
new_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the value passed in would mean seeking beyond the end of the track, acts like a call to Next.
|
||||||
|
if new_position >= (playbin.duration() * MICROSECONDS) as i64 {
|
||||||
|
return self.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
playbin.seek(new_position as f64 / MICROSECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_position(&self, _track_id: ObjectPath<'_>, _position: i64) {
|
fn set_position(&self, track_id: ObjectPath<'_>, position: i64) {
|
||||||
todo!()
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
|
||||||
|
// If the Position argument is less than 0, do nothing.
|
||||||
|
if position < 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the Position argument is greater than the track length, do nothing.
|
||||||
|
if position > (playbin.duration() * MICROSECONDS) as i64 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the CanSeek property is false, this has no effect.
|
||||||
|
if !self.can_seek() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check if it's stale
|
||||||
|
if self.metadata.track_id.as_deref() != Some(&track_id) {
|
||||||
|
// TODO: warn of stale seek
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playbin.seek(position as f64 / MICROSECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_uri(&self, _s: &str) {
|
fn open_uri(&self, _s: &str) -> zbus::fdo::Result<()> {
|
||||||
todo!()
|
Err(zbus::fdo::Error::NotSupported("OpenUri".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(signal)]
|
#[zbus(signal)]
|
||||||
|
@ -109,8 +257,8 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn set_playback_rate(&self, _playback_rate: f64) {
|
fn set_playback_rate(&self, _playback_rate: f64) -> zbus::Result<()> {
|
||||||
todo!()
|
Err(zbus::Error::Unsupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
|
@ -124,11 +272,8 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn metadata(&self) -> Vec<(String, Value)> {
|
fn metadata(&self) -> HashMap<&'static str, Value> {
|
||||||
self.metadata
|
self.metadata.as_hash_map()
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.clone(), v.into()))
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
|
@ -137,13 +282,15 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn set_volume(&self, _volume: f64) {
|
fn set_volume(&mut self, volume: f64) {
|
||||||
todo!()
|
let playbin = self.playbin.upgrade().unwrap();
|
||||||
|
// FIXME: check if this is set by the notify callback: self.volume = volume;
|
||||||
|
playbin.set_volume((volume * 100.0) as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property(emits_changed_signal = "false"))]
|
#[zbus(property(emits_changed_signal = "false"))]
|
||||||
fn position(&self) -> i64 {
|
fn position(&self) -> i64 {
|
||||||
(self.playbin.upgrade().unwrap().position() * 1e9) as i64
|
(self.playbin.upgrade().unwrap().position() * MICROSECONDS) as i64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
|
@ -158,31 +305,31 @@ impl Player {
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn can_go_next(&self) -> bool {
|
fn can_go_next(&self) -> bool {
|
||||||
false // TODO
|
self.playbin.upgrade().unwrap().state() != crate::playbin::State::Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn can_go_previous(&self) -> bool {
|
fn can_go_previous(&self) -> bool {
|
||||||
false // TODO
|
self.playbin.upgrade().unwrap().state() != crate::playbin::State::Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn can_play(&self) -> bool {
|
fn can_play(&self) -> bool {
|
||||||
false // TODO
|
self.playbin.upgrade().unwrap().state() != crate::playbin::State::Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn can_pause(&self) -> bool {
|
fn can_pause(&self) -> bool {
|
||||||
false // TODO
|
self.playbin.upgrade().unwrap().state() != crate::playbin::State::Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn can_seek(&self) -> bool {
|
fn can_seek(&self) -> bool {
|
||||||
false // TODO
|
self.playbin.upgrade().unwrap().state() != crate::playbin::State::Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property(emits_changed_signal = "const"))]
|
#[zbus(property(emits_changed_signal = "const"))]
|
||||||
fn can_control(&self) -> bool {
|
fn can_control(&self) -> bool {
|
||||||
false // TODO
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub mod ffi {
|
||||||
pub fn audrey_playbin_get_play_queue_position(
|
pub fn audrey_playbin_get_play_queue_position(
|
||||||
self_: *mut AudreyPlaybin,
|
self_: *mut AudreyPlaybin,
|
||||||
) -> std::ffi::c_uint;
|
) -> std::ffi::c_uint;
|
||||||
|
pub fn audrey_playbin_get_play_queue_length(self_: *mut AudreyPlaybin) -> std::ffi::c_uint;
|
||||||
pub fn audrey_playbin_move_track(
|
pub fn audrey_playbin_move_track(
|
||||||
self_: *mut AudreyPlaybin,
|
self_: *mut AudreyPlaybin,
|
||||||
from: std::ffi::c_uint,
|
from: std::ffi::c_uint,
|
||||||
|
@ -111,6 +112,10 @@ impl Playbin {
|
||||||
unsafe { ffi::audrey_playbin_get_play_queue_position(self.to_glib_none().0) }
|
unsafe { ffi::audrey_playbin_get_play_queue_position(self.to_glib_none().0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn play_queue_length(&self) -> u32 {
|
||||||
|
unsafe { ffi::audrey_playbin_get_play_queue_length(self.to_glib_none().0) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_track(&self, from: u32, to: u32) {
|
pub fn move_track(&self, from: u32, to: u32) {
|
||||||
unsafe { ffi::audrey_playbin_move_track(self.to_glib_none().0, from, to) }
|
unsafe { ffi::audrey_playbin_move_track(self.to_glib_none().0, from, to) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class Audrey.Playbin : GLib.Object {
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
_volume = value;
|
_volume = value;
|
||||||
} else {
|
} else {
|
||||||
warning ("failed to set volume: %s", ret.to_string ());
|
warning ("failed to set volume to %d: %s", value, ret.to_string ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,9 +98,11 @@ public class Audrey.Playbin : GLib.Object {
|
||||||
public int play_queue_position { get; private set; default = -1; }
|
public int play_queue_position { get; private set; default = -1; }
|
||||||
|
|
||||||
// signalled when a new track is current
|
// signalled when a new track is current
|
||||||
public signal void new_track ();
|
public signal void new_track (PlaybinSong song);
|
||||||
// signalled when the last track is over
|
// signalled when the last track is over
|
||||||
public signal void stopped ();
|
public signal void stopped ();
|
||||||
|
// signalled when the position changes discontinuously
|
||||||
|
public signal void seeked (double position);
|
||||||
|
|
||||||
// these are mostly synced with mpv
|
// these are mostly synced with mpv
|
||||||
public double position { get; private set; default = 0.0; }
|
public double position { get; private set; default = 0.0; }
|
||||||
|
@ -211,9 +213,10 @@ public class Audrey.Playbin : GLib.Object {
|
||||||
|
|
||||||
// estimate duration from api data
|
// estimate duration from api data
|
||||||
// while mpv doesn't know it
|
// while mpv doesn't know it
|
||||||
this.duration = ((PlaybinSong) this._play_queue.get_item (this.play_queue_position)).duration;
|
var song = (PlaybinSong) this._play_queue.get_item (this.play_queue_position);
|
||||||
|
this.duration = song.duration;
|
||||||
|
|
||||||
this.new_track ();
|
this.new_track (song);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Mpv.EventId.END_FILE:
|
case Mpv.EventId.END_FILE:
|
||||||
|
@ -262,6 +265,7 @@ public class Audrey.Playbin : GLib.Object {
|
||||||
warning (@"could not seek to $position: $rc");
|
warning (@"could not seek to $position: $rc");
|
||||||
} else {
|
} else {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
this.seeked (position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@ pub struct Child {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub album: String,
|
pub album: String,
|
||||||
pub artist: String,
|
pub artist: String,
|
||||||
pub track: u32,
|
pub track: Option<u32>,
|
||||||
pub year: u32,
|
pub year: Option<u32>,
|
||||||
pub starred: Option<()>,
|
pub starred: Option<()>,
|
||||||
pub duration: u64,
|
pub duration: u64,
|
||||||
pub play_count: Option<u32>,
|
pub play_count: Option<u32>,
|
||||||
|
|
|
@ -29,8 +29,6 @@ public class Audrey.Ui.Window : Adw.ApplicationWindow {
|
||||||
Object (application: app);
|
Object (application: app);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MprisPlayer mpris_player;
|
|
||||||
|
|
||||||
private void now_playing (PlaybinSong song) {
|
private void now_playing (PlaybinSong song) {
|
||||||
this.song = song;
|
this.song = song;
|
||||||
// api.scrobble.begin (this.song.id); TODO
|
// api.scrobble.begin (this.song.id); TODO
|
||||||
|
|
Loading…
Reference in a new issue