build,core,plugins: Port to GDBus and GVariant
[profile/ivi/rygel.git] / src / plugins / mpris / rygel-mpris-player.vala
1 /*
2  * Copyright (C) 2008 OpenedHand Ltd.
3  * Copyright (C) 2009 Nokia Corporation.
4  *
5  * Author: Jorn Baayen <jorn@openedhand.com>
6  *         Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
7  *                               <zeeshan.ali@nokia.com>
8  *
9  * Rygel is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Rygel is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 using Rygel.MPRIS;
25 using Rygel.MPRIS.MediaPlayer;
26 using FreeDesktop;
27
28 public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
29     private string[] protocols;
30     private string[] mime_types;
31
32     private PlayerProxy actual_player;
33     private Properties properties;
34
35     public string playback_state {
36         owned get {
37             return this.mpris_to_upnp_state (actual_player.playback_status);
38         }
39
40         set {
41             debug ("Changing playback state to %s..", value);
42
43             /* FIXME: Do something about errors below */
44             switch (value) {
45             case "STOPPED":
46                 try {
47                     this.actual_player.stop ();
48                 } catch (Error error) {}
49
50                 break;
51             case "PAUSED_PLAYBACK":
52                 try {
53                     this.actual_player.pause ();
54                 } catch (Error error) {}
55
56                 break;
57             case "PLAYING":
58                 try {
59                     this.actual_player.play ();
60                 } catch (Error error) {}
61
62                 break;
63             default:
64                 assert_not_reached ();
65             }
66         }
67     }
68
69     public string? uri {
70         owned get {
71             var val = this.actual_player.metadata.lookup ("xesam:url");
72
73             if (val != null) {
74                 return (string) val;
75             } else {
76                 return null;
77             }
78         }
79
80         set {
81             try {
82                 this.actual_player.open_uri (value);
83             } catch (Error error) {}
84         }
85     }
86
87     public double volume {
88         get {
89             return this.actual_player.volume;
90         }
91
92         set {
93             this.actual_player.volume = value;
94         }
95     }
96
97     public int64 duration {
98         get {
99             var val = this.actual_player.metadata.lookup ("mpris:length");
100             int64 dur = 0;
101
102             if (val != null) {
103                 dur = (int64) val * 1000;
104             }
105
106             return dur;
107         }
108     }
109
110     public int64 position {
111         get {
112             return this.actual_player.position * 1000;
113         }
114     }
115
116     public Player (PlayerProxy actual_player,
117                    Properties  properties,
118                    string[]    mime_types,
119                    string[]    protocols) {
120         this.actual_player = actual_player;
121         this.properties = properties;
122         this.mime_types = mime_types;
123         this.protocols = protocols;
124
125         this.properties.properties_changed.connect (this.on_properties_changed);
126     }
127
128     public bool seek (Gst.ClockTime time) {
129         var ret = false;
130
131         try {
132             this.actual_player.seek (time / 1000);
133             ret = true;
134         } catch (Error error) {}
135
136         return ret;
137     }
138
139     public string[] get_protocols () {
140         return this.protocols;
141     }
142
143     public string[] get_mime_types () {
144         return this.mime_types;
145     }
146
147     private string mpris_to_upnp_state (string state) {
148         switch (state) {
149         case "Stopped":
150             return "STOPPED";
151         case "Paused":
152             return "PAUSED_PLAYBACK";
153         case "Playing":
154             return "PLAYING";
155         default:
156             assert_not_reached ();
157         }
158     }
159
160     private void on_properties_changed (string                    iface,
161                                         HashTable<string,Variant> changed,
162                                         string[]                  invalidated) {
163         if (changed.lookup ("PlaybackStatus") != null) {
164             this.notify_property ("playback-state");
165         }
166
167         if (changed.lookup ("Volume") != null) {
168             this.notify_property ("volume");
169         }
170
171         if (changed.lookup ("Metadata") != null) {
172             var metadata = this.actual_player.metadata;
173
174             if (metadata.lookup ("xesam:url") != null) {
175                 this.notify_property ("uri");
176             }
177
178             if (metadata.lookup ("mpris:length") != null) {
179                 this.notify_property ("duration");
180             }
181         }
182     }
183 }