aboutsummaryrefslogtreecommitdiff
path: root/src/mpris2-controller.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/mpris2-controller.vala')
-rw-r--r--src/mpris2-controller.vala183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala
new file mode 100644
index 0000000..20cfc9e
--- /dev/null
+++ b/src/mpris2-controller.vala
@@ -0,0 +1,183 @@
+/*
+This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+using Gee;
+
+[DBus (name = "org.mpris.MediaPlayer.Player")]
+public interface MprisPlayer : Object {
+
+ public struct Status {
+ public int32 Playback_State;
+ public double Playback_Rate;
+ public bool Repeat_State;
+ public bool Shuffle_State;
+ public bool Endless_State;
+ }
+
+ public abstract HashTable<string, Value?> Metadata{owned get;}
+ public abstract double Volume{get;}
+ public abstract int32 Capabilities{get;}
+ public abstract int32 Position{get;}
+
+ public abstract void SetPosition(string prop, int32 pos) throws DBus.Error;
+ public abstract void PlayPause() throws DBus.Error;
+ public abstract void Pause() throws DBus.Error;
+ public abstract void Next() throws DBus.Error;
+ public abstract void Previous() throws DBus.Error;
+
+ public abstract signal void StatusChanged(Status update);
+ public abstract signal void TrackChanged(HashTable<string,Value?> Metadata);
+}
+
+/*
+ This class will entirely replace mpris-controller.vala hence why there is no
+ point in trying to get encorporate both into the same object model.
+ */
+public class Mpris2Controller : GLib.Object
+{
+ private DBus.Connection connection;
+ public dynamic DBus.Object mpris2_root {get; construct;}
+ public MprisPlayer mpris2_player {get; construct;}
+ public PlayerController owner {get; construct;}
+
+ public Mpris2Controller(PlayerController ctrl)
+ {
+ Object(owner: ctrl);
+ }
+
+ construct{
+ try {
+ debug("going to create this mpris 2 controller");
+ this.connection = DBus.Bus.get (DBus.BusType.SESSION);
+ } catch (Error e) {
+ error("Problems connecting to the session bus - %s", e.message);
+ }
+ this.mpris2_root = this.connection.get_object ("org.mpris.mediaplayers.".concat(this.owner.name.down()),
+ "/org/mpris/MediaPlayer",
+ "org.mpris.MediaPlayer");
+
+ this.mpris2_player = (MprisPlayer)this.connection.get_object ("org.mpris.mediaplayers.".concat(this.owner.name.down()) ,
+ "/org/mpris/MediaPlayer/Player",
+ "org.mpris.MediaPlayer.Player");
+ this.mpris2_player.TrackChanged += onTrackChanged;
+ this.mpris2_player.StatusChanged += onStatusChanged;
+ initial_update();
+ }
+
+ private void initial_update()
+ {
+ bool r = (bool)this.mpris2_player.Status.Shuffle_State;
+ int32 p = (int32)this.mpris2_player.Status.Playback_State;
+
+ debug("initial update - play state %i", p);
+ debug("initial update - shuffle state %s", r.to_string());
+
+ (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p);
+ this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.mpris2_player.Metadata,
+ MetadataMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris2_player.Metadata,
+ ScrubMenuitem.attributes_format());
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+
+ }
+
+ public void transport_event(TransportMenuitem.action command)
+ {
+ debug("transport_event input = %i", (int)command);
+ if(command == TransportMenuitem.action.PLAY_PAUSE){
+ debug("transport_event PLAY_PAUSE");
+ this.mpris2_player.PlayPause();
+ }
+ else if(command == TransportMenuitem.action.PREVIOUS){
+ this.mpris2_player.Previous();
+ }
+ else if(command == TransportMenuitem.action.NEXT){
+ this.mpris2_player.Next();
+ }
+ }
+
+ public void set_position(double position)
+ {
+ debug("Set position with pos (0-100) %f", position);
+ HashTable<string, Value?> data = this.mpris2_player.Metadata;
+ Value? time_value = data.lookup("time");
+ if(time_value == null){
+ warning("Can't fetch the duration of the track therefore cant set the position");
+ return;
+ }
+ uint32 total_time = time_value.get_uint();
+ debug("total time of track = %i", (int)total_time);
+ double new_time_position = total_time * position/100.0;
+ debug("new position = %f", (new_time_position * 1000));
+
+ Value? v = this.mpris2_player.Metadata.lookup("trackid");
+ if(v != null){
+ if(v.holds (typeof (int))){
+ debug("the trackid = %i", v.get_int());
+ }
+ else if(v.holds (typeof (string))){
+ debug("the trackid = %s", v.get_string());
+ }
+ }
+
+ //this.mpris2_player.SetPosition((int32)(new_time_position));
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+ }
+
+ public bool connected()
+ {
+ return (this.mpris2_player != null);
+ }
+
+ private void onStatusChanged(MprisPlayer.Status st)
+ {
+ debug("onStatusChange - play state %i", st.Playback_State);
+ HashTable<string, Value?> ht = new HashTable<string, Value?>(str_hash, str_equal);
+ Value v = Value(typeof(int));
+ v.set_int(st.Playback_State);
+ ht.insert("state", v);
+ this.owner.custom_items[PlayerController.widget_order.TRANSPORT].update(ht, TransportMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(ht, ScrubMenuitem.attributes_format());
+ }
+
+ private void onTrackChanged(HashTable<string,Value?> ht)
+ {
+ this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.METADATA].update(ht,
+ MetadataMenuitem.attributes_format());
+ debug("about to update the duration on the scrub bar");
+ Value? v = ht.lookup("time");
+ if(v != null)
+ {
+ debug("with the duration of %i", (int)v.get_uint());
+ debug("with Position of %i", this.mpris2_player.Position);
+ }
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(ht,
+ ScrubMenuitem.attributes_format());
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+ }
+
+}
+
+
+