Compare commits
No commits in common. "efc639367bb20984ab65d06540ce543e38c792b2" and "8c4c4f8e74f81a6f3a0aafdefbbf94730b57191a" have entirely different histories.
efc639367b
...
8c4c4f8e74
3 changed files with 24 additions and 205 deletions
190
src/mpris.vala
190
src/mpris.vala
|
@ -21,11 +21,6 @@ class Mpris : Object {
|
||||||
public string[] supported_uri_schemes { owned get { return {}; } }
|
public string[] supported_uri_schemes { owned get { return {}; } }
|
||||||
public string[] supported_mime_types { owned get { return {}; } }
|
public string[] supported_mime_types { owned get { return {}; } }
|
||||||
|
|
||||||
internal Mpris (Ui.Window window) {
|
|
||||||
this.on_raise.connect (() => window.present ());
|
|
||||||
this.on_quit.connect (() => window.close ());
|
|
||||||
}
|
|
||||||
|
|
||||||
~Mpris () {
|
~Mpris () {
|
||||||
debug ("destroying mpris");
|
debug ("destroying mpris");
|
||||||
}
|
}
|
||||||
|
@ -55,187 +50,22 @@ class 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_map { owned get; 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)]
|
||||||
public int64 position { get; default = 0; }
|
public int64 position { get; default = 0; }
|
||||||
public double minimum_rate { get { return 1.0; } }
|
public double minimum_rate { get { return 1.0; } }
|
||||||
public double maximum_rate { get { return 1.0; } }
|
public double maximum_rate { get { return 1.0; } }
|
||||||
public bool can_go_next { get; private set; default = false; }
|
public bool can_go_next { get; default = false; }
|
||||||
public bool can_go_previous { get; private set; default = false; }
|
public bool can_go_previous { get; default = false; }
|
||||||
public bool can_play { get; private set; default = false; }
|
public bool can_play { get; default = false; }
|
||||||
public bool can_pause { get; private set; default = false; }
|
public bool can_pause { get; default = false; }
|
||||||
public bool can_seek { get; private set; default = false; }
|
public bool can_seek { get; default = false; }
|
||||||
[CCode (notify = false)]
|
[CCode (notify = false)]
|
||||||
public bool can_control { get { return true; } }
|
public bool can_control { get { return false; } }
|
||||||
|
|
||||||
internal MprisPlayer (DBusConnection conn, Playbin playbin) {
|
|
||||||
playbin.bind_property (
|
|
||||||
"state",
|
|
||||||
this,
|
|
||||||
"playback_status",
|
|
||||||
BindingFlags.DEFAULT,
|
|
||||||
(binding, from, ref to) => {
|
|
||||||
switch (from.get_enum ()) {
|
|
||||||
case PlaybinState.STOPPED:
|
|
||||||
to.set_string ("Stopped");
|
|
||||||
this.can_go_next = false;
|
|
||||||
this.can_go_previous = false;
|
|
||||||
this.can_play = false;
|
|
||||||
this.can_pause = false;
|
|
||||||
this.can_seek = false;
|
|
||||||
return true;
|
|
||||||
case PlaybinState.PAUSED:
|
|
||||||
to.set_string ("Paused");
|
|
||||||
this.can_go_next = true;
|
|
||||||
this.can_go_previous = true;
|
|
||||||
this.can_play = true;
|
|
||||||
this.can_pause = true;
|
|
||||||
this.can_seek = true;
|
|
||||||
return true;
|
|
||||||
case PlaybinState.PLAYING:
|
|
||||||
to.set_string ("Playing");
|
|
||||||
this.can_go_next = true;
|
|
||||||
this.can_go_previous = true;
|
|
||||||
this.can_play = true;
|
|
||||||
this.can_pause = true;
|
|
||||||
this.can_seek = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
playbin.bind_property (
|
|
||||||
"volume",
|
|
||||||
this,
|
|
||||||
"volume",
|
|
||||||
BindingFlags.BIDIRECTIONAL,
|
|
||||||
(binding, from, ref to) => {
|
|
||||||
to.set_double (from.get_int () / 100.0);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
(binding, from, ref to) => {
|
|
||||||
to.set_int ((int) (from.get_double () * 100.0));
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
playbin.new_track.connect ((playbin) => {
|
|
||||||
Subsonic.Song song = (Subsonic.Song) playbin.play_queue.get_item (playbin.play_queue_position);
|
|
||||||
|
|
||||||
var metadata = new HashTable<string, Variant> (null, null);
|
|
||||||
metadata["mpris:trackid"] = new ObjectPath (@"/eu/callcc/audrey/track/$(song.id)");
|
|
||||||
metadata["mpris:length"] = (int64) song.duration * 1000000;
|
|
||||||
// TODO: metadata["mpris:artUrl"] =
|
|
||||||
metadata["xesam:album"] = song.album;
|
|
||||||
metadata["xesam:artist"] = new string[] {song.artist};
|
|
||||||
if (song.genre != null) metadata["xesam:genre"] = song.genre;
|
|
||||||
metadata["xesam:title"] = song.title;
|
|
||||||
metadata["xesam:trackNumber"] = song.track;
|
|
||||||
metadata["xesam:useCount"] = song.play_count;
|
|
||||||
metadata["xesam:userRating"] = song.starred != null ? 1.0 : 0.0;
|
|
||||||
|
|
||||||
this.metadata = metadata;
|
|
||||||
});
|
|
||||||
|
|
||||||
playbin.stopped.connect (() => {
|
|
||||||
this.metadata = new HashTable<string, Variant> (null, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.on_next.connect (() => playbin.go_to_next_track ());
|
|
||||||
this.on_previous.connect (() => playbin.go_to_prev_track ());
|
|
||||||
this.on_play.connect (() => playbin.play ());
|
|
||||||
this.on_pause.connect (() => playbin.pause ());
|
|
||||||
this.on_play_pause.connect (() => {
|
|
||||||
if (playbin.state == PlaybinState.PAUSED) playbin.play ();
|
|
||||||
else if (playbin.state == PlaybinState.PLAYING) playbin.pause ();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.notify.connect ((p) => {
|
|
||||||
var builder = new VariantBuilder (VariantType.ARRAY);
|
|
||||||
var invalid_builder = new VariantBuilder (new VariantType ("as"));
|
|
||||||
|
|
||||||
string dbus_name;
|
|
||||||
Variant dbus_value;
|
|
||||||
|
|
||||||
switch (p.name) {
|
|
||||||
case "playback-status":
|
|
||||||
dbus_name = "PlaybackStatus";
|
|
||||||
dbus_value = this.playback_status;
|
|
||||||
break;
|
|
||||||
case "loop-status":
|
|
||||||
dbus_name = "LoopStatus";
|
|
||||||
dbus_value = this.loop_status;
|
|
||||||
break;
|
|
||||||
case "rate":
|
|
||||||
dbus_name = "Rate";
|
|
||||||
dbus_value = this.rate;
|
|
||||||
break;
|
|
||||||
case "shuffle":
|
|
||||||
dbus_name = "Shuffle";
|
|
||||||
dbus_value = this.shuffle;
|
|
||||||
break;
|
|
||||||
case "metadata":
|
|
||||||
dbus_name = "Metadata";
|
|
||||||
dbus_value = this.metadata;
|
|
||||||
break;
|
|
||||||
case "volume":
|
|
||||||
dbus_name = "Volume";
|
|
||||||
dbus_value = this.volume;
|
|
||||||
break;
|
|
||||||
case "minimum-rate":
|
|
||||||
dbus_name = "MinimumRate";
|
|
||||||
dbus_value = this.minimum_rate;
|
|
||||||
break;
|
|
||||||
case "maximum-rate":
|
|
||||||
dbus_name = "MaximumRate";
|
|
||||||
dbus_value = this.maximum_rate;
|
|
||||||
break;
|
|
||||||
case "can-go-next":
|
|
||||||
dbus_name = "CanGoNext";
|
|
||||||
dbus_value = this.can_go_next;
|
|
||||||
break;
|
|
||||||
case "can-go-previous":
|
|
||||||
dbus_name = "CanGoPrevious";
|
|
||||||
dbus_value = this.can_go_previous;
|
|
||||||
break;
|
|
||||||
case "can-play":
|
|
||||||
dbus_name = "CanPlay";
|
|
||||||
dbus_value = this.can_play;
|
|
||||||
break;
|
|
||||||
case "can-pause":
|
|
||||||
dbus_name = "CanPause";
|
|
||||||
dbus_value = this.can_pause;
|
|
||||||
break;
|
|
||||||
case "can-seek":
|
|
||||||
dbus_name = "CanSeek";
|
|
||||||
dbus_value = this.can_seek;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
warning (@"unknown mpris player property $(p.name)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.add ("{sv}", dbus_name, dbus_value);
|
|
||||||
|
|
||||||
try {
|
|
||||||
conn.emit_signal (
|
|
||||||
null,
|
|
||||||
"/org/mpris/MediaPlayer2",
|
|
||||||
"org.freedesktop.DBus.Properties",
|
|
||||||
"PropertiesChanged",
|
|
||||||
new Variant (
|
|
||||||
"(sa{sv}as)",
|
|
||||||
"org.mpris.MediaPlayer2.Player",
|
|
||||||
builder,
|
|
||||||
invalid_builder));
|
|
||||||
} catch (Error e) {
|
|
||||||
error (@"could not notify of mpris property changes: $(e.message)");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~MprisPlayer () {
|
~MprisPlayer () {
|
||||||
debug ("destroying mpris player");
|
debug ("destroying mpris player");
|
||||||
|
|
|
@ -60,10 +60,8 @@ public class Subsonic.Song : Object {
|
||||||
public string artist { get; private set; }
|
public string artist { get; private set; }
|
||||||
public int64 track { get; private set; }
|
public int64 track { get; private set; }
|
||||||
public int64 year { get; private set; }
|
public int64 year { get; private set; }
|
||||||
public DateTime? starred { get; private set; } // TODO
|
public DateTime? starred { get; private set; }
|
||||||
public int64 duration { get; private set; }
|
public int64 duration { get; private set; }
|
||||||
public int64 play_count { get; private set; }
|
|
||||||
public string? genre { get; private set; }
|
|
||||||
|
|
||||||
public Song (Json.Reader reader) {
|
public Song (Json.Reader reader) {
|
||||||
reader.read_member ("id");
|
reader.read_member ("id");
|
||||||
|
@ -93,14 +91,6 @@ public class Subsonic.Song : Object {
|
||||||
reader.read_member ("duration");
|
reader.read_member ("duration");
|
||||||
this.duration = reader.get_int_value ();
|
this.duration = reader.get_int_value ();
|
||||||
reader.end_member ();
|
reader.end_member ();
|
||||||
|
|
||||||
reader.read_member ("playCount");
|
|
||||||
this.play_count = reader.get_int_value ();
|
|
||||||
reader.end_member ();
|
|
||||||
|
|
||||||
reader.read_member ("genre");
|
|
||||||
this.genre = reader.get_string_value ();
|
|
||||||
reader.end_member ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,20 +56,19 @@ class Ui.Window : Adw.ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
construct {
|
construct {
|
||||||
Bus.own_name (
|
// TODO: mpris
|
||||||
BusType.SESSION,
|
// Bus.own_name (
|
||||||
"org.mpris.MediaPlayer2.audrey",
|
// BusType.SESSION,
|
||||||
BusNameOwnerFlags.NONE,
|
// "org.mpris.MediaPlayer2.audrey",
|
||||||
(conn) => {
|
// BusNameOwnerFlags.NONE,
|
||||||
try {
|
// (conn) => {
|
||||||
conn.register_object ("/org/mpris/MediaPlayer2", new Mpris (this));
|
// try {
|
||||||
conn.register_object ("/org/mpris/MediaPlayer2", new MprisPlayer (conn, this.playbin));
|
// } catch (IOError e) {
|
||||||
} catch (IOError e) {
|
// error ("could not register dbus service: %s", e.message);
|
||||||
error ("could not register dbus service: %s", e.message);
|
// }
|
||||||
}
|
// },
|
||||||
},
|
// () => {},
|
||||||
() => {},
|
// () => { error ("could not acquire dbus name"); });
|
||||||
() => { error ("could not acquire dbus name"); });
|
|
||||||
|
|
||||||
this.setup = new Setup ();
|
this.setup = new Setup ();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue