~dhananjaysathe/nuvola-player/TelepathyExt

« back to all changes in this revision

Viewing changes to src/player.vala

  • Committer: Jiří Janoušek
  • Date: 2011-08-23 23:07:29 UTC
  • Revision ID: janousek.jiri@gmail.com-20110823230729-0lfuuttyps70qd58
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Google Music Frame
 
3
 
 
4
Copyright 2011 Jiří Janoušek <janousek.jiri@gmail.com>
 
5
 
 
6
This program is free software: you can redistribute it and/or modify it 
 
7
under the terms of the GNU General Public License version 3, as published 
 
8
by the Free Software Foundation.
 
9
 
 
10
This program is distributed in the hope that it will be useful, but 
 
11
WITHOUT ANY WARRANTY; without even the implied warranties of 
 
12
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
13
PURPOSE.  See the GNU General Public License for more details.
 
14
 
 
15
You should have received a copy of the GNU General Public License along 
 
16
with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
*/
 
18
 
 
19
/* http://www.mpris.org/2.1/spec/Player_Node.html */
 
20
[DBus(name = "org.mpris.MediaPlayer2.Player")]
 
21
public class GMF.Player : GLib.Object{
 
22
        private Frame frame;
 
23
        private DBusConnection conn;
 
24
        private HashTable<string,Variant> song_info;
 
25
        
 
26
        public Player(Application app, DBusConnection conn){
 
27
                this.frame = app.frame;
 
28
                this.conn = conn;
 
29
                this.song_info = new HashTable<string,Variant>(null, null);
 
30
                this.notify.connect(this.send_property_change);
 
31
                this.frame.song_changed.connect(this.on_song_changed);
 
32
                this.frame.playback_state_changed.connect(this.on_playback_state_changed);
 
33
        }
 
34
        
 
35
        private void send_property_change (ParamSpec p) {
 
36
        var builder = new VariantBuilder (VariantType.ARRAY);
 
37
        var invalid_builder = new VariantBuilder (new VariantType ("as"));
 
38
                debug("send changed %s", p.name);
 
39
                Variant i;
 
40
                switch(p.name){
 
41
                        case "Metadata":
 
42
                                i = this.Metadata;
 
43
                                builder.add ("{sv}", "Metadata", i);
 
44
                                break;
 
45
                        case "can-go-previous":
 
46
                                i = this.can_go_previous;
 
47
                                builder.add ("{sv}", "CanGoPrevious", i);
 
48
                                break;
 
49
                        case "can-go-next":
 
50
                                i = this.can_go_next;
 
51
                                builder.add ("{sv}", "CanGoNext", i);
 
52
                                break;
 
53
                        case "can-play":
 
54
                                i = this.can_play;
 
55
                                builder.add ("{sv}", "CanPlay", i);
 
56
                                break;
 
57
                        case "can-pause":
 
58
                                i = this.can_pause;
 
59
                                builder.add ("{sv}", "CanPause", i);
 
60
                                break;
 
61
                        case "playback-status":
 
62
                                i = this.playback_status;
 
63
                                builder.add ("{sv}", "PlaybackStatus", i);
 
64
                                break;
 
65
                        default:
 
66
                                warning("Unhandled property: %s", p.name);
 
67
                                return;
 
68
                }
 
69
                
 
70
                var v = new Variant("(sa{sv}as)", "org.mpris.MediaPlayer2.Player", 
 
71
                                                        builder, invalid_builder);
 
72
        try {
 
73
            conn.emit_signal ("org.mpris.MediaPlayer2.googlemusicframe",
 
74
                                                                "/org/mpris/MediaPlayer2", 
 
75
                                                "org.freedesktop.DBus.Properties", 
 
76
                                                        "PropertiesChanged", v  );
 
77
 
 
78
        } catch (Error e) {
 
79
            stderr.printf ("%s\n", e.message);
 
80
        }
 
81
    }
 
82
    
 
83
    private void on_song_changed(string? art, string? artist, string? song){
 
84
                var info = new HashTable<string,Variant>(null, null);
 
85
                string[] artistArray = {};
 
86
                if(artist != null) artistArray += artist;
 
87
                info.insert("xesam:artist", artistArray);
 
88
                if(song != null) info.insert("xesam:title", song);
 
89
                if(art != null) info.insert("mpris:artUrl", art);
 
90
                this.Metadata = info;
 
91
        }
 
92
        
 
93
        private void on_playback_state_changed(string state, bool can_prev, bool can_next){
 
94
                this.playback_status = state == "none" ? "Stopped"
 
95
                        : (state == "paused" ? "Paused" : "Playing");
 
96
                
 
97
                this.can_go_previous = can_prev;
 
98
                this.can_go_next = can_next;
 
99
                this.can_pause = this.can_play = state != "none";               
 
100
        }
 
101
        
 
102
        /* Properties: http://www.mpris.org/2.1/spec/Player_Node.html#properties */
 
103
        
 
104
        [Description(nick = "The current playback status.", blurb = "The current playback status. May be 'Playing', 'Paused' or 'Stopped'.")]
 
105
        public string playback_status { owned get; private set; default = "Stopped";}
 
106
        
 
107
        [Description(nick = "The current loop / repeat status", blurb = "May be: 'None' if the playback will stop when there are no more tracks to play. 'Track' if the current track will start again from the begining once it has finished playing. 'Playlist' if the playback loops through a list of tracks.")]
 
108
        public string LoopStatus{
 
109
                owned get{
 
110
                        return "None";
 
111
                        return "Track";
 
112
                        return "Playlist";
 
113
                }
 
114
                set{
 
115
                        switch(value){
 
116
                                case("None"):
 
117
                                        break;
 
118
                                case("Track"):
 
119
                                        break;
 
120
                                case("Playlist"):
 
121
                                        break;
 
122
                                default:
 
123
                                        break;
 
124
                        }
 
125
                }
 
126
        }
 
127
        
 
128
//~     [Description(nick = "The current playback rate.", blurb = "The current playback rate.")]
 
129
//~     public double Rate{
 
130
//~             get{
 
131
//~                     return (double)1.0;
 
132
//~             }
 
133
//~             set{
 
134
//~             }
 
135
//~     }
 
136
//~     
 
137
//~     [Description(nick = "Minimum playback rate.", blurb = "Minimum playback rate.")]
 
138
//~     public double MinimumRate{
 
139
//~             get{
 
140
//~                     return (double)1.0;
 
141
//~             }
 
142
//~     }
 
143
//~     
 
144
//~     [Description(nick = "Maximum playback rate.", blurb = "Maximum playback rate.")]
 
145
//~     public double MaximumRate{
 
146
//~             get{
 
147
//~                     return (double)1.0;
 
148
//~             }
 
149
//~     }
 
150
        
 
151
        [Description(nick = "Shuffle state", blurb = "A value of false indicates that playback is progressing linearly through a playlist, while true means playback is progressing through a playlist in some other order.")]
 
152
        public bool Shuffle{
 
153
                get{
 
154
                        return true;
 
155
                        return false;
 
156
                }
 
157
                set{
 
158
                        if(value){
 
159
                        }
 
160
                        else{
 
161
                        }
 
162
                }
 
163
        }
 
164
        
 
165
        [Description(nick = "The metadata of the current element.", blurb = "The metadata of the current element.")]
 
166
        public HashTable<string,Variant>? Metadata{
 
167
                owned get{
 
168
                        Variant variant = "1";
 
169
                        this.song_info.insert("mpris:trackid", variant);
 
170
                        return this.song_info;
 
171
                }
 
172
                private set{
 
173
                        this.song_info = value;
 
174
                }
 
175
        }
 
176
        
 
177
//~     [Description(nick = "The volume level.", blurb = "The volume level.")]
 
178
//~     public double Volume{
 
179
//~             owned get{
 
180
//~                     return (double)1.0;
 
181
//~             }
 
182
//~             set {
 
183
//~                     
 
184
//~             }
 
185
//~     }
 
186
        
 
187
        [Description(nick = "The current track position in microseconds.", blurb = "The current track position in microseconds.")]
 
188
        public int64 Position{
 
189
                get{
 
190
                        return (int64)1;
 
191
                }
 
192
        }
 
193
        
 
194
        [Description(nick = "Next song action availability", blurb = "Whether the client can call the Next method on this interface and expect the current track to change.")]
 
195
        public bool can_go_next{ get; private set; default = false; }                   
 
196
        
 
197
        [Description(nick = "Previous song action availability", blurb = "Whether the client can call the Previous method on this interface and expect the current track to change.")]
 
198
        public bool can_go_previous{ get; private set; default = false; }
 
199
        
 
200
        [Description(nick = "Play action availability", blurb = "Whether playback can be started using Play or PlayPause.")]
 
201
        public bool can_play{ get; private set; default = false; }
 
202
        
 
203
        [Description(nick = "Pause action availability", blurb = "Whether playback can be paused using Pause or PlayPause.")]
 
204
        public bool can_pause{ get; private set; default = false; }
 
205
        
 
206
        [Description(nick = "Seek action availability", blurb = "Whether the client can control the playback position using Seek and SetPosition. This may be different for different tracks.")]
 
207
        public bool CanSeek{
 
208
                get{
 
209
                        return false;
 
210
                }
 
211
        }
 
212
        
 
213
        [Description(nick = "Whether the media player may be controlled.", blurb = "Whether the media player may be controlled over this interface.")]
 
214
        public bool CanControl{
 
215
                get{
 
216
                        return true;
 
217
                }
 
218
        }
 
219
        
 
220
        /* Signals: http://www.mpris.org/2.1/spec/Player_Node.html#signals */
 
221
        /**
 
222
         * Indicates that the track position has changed in a way that is inconsistant with the current playing state.
 
223
         * @param Position The new position, in microseconds.
 
224
         */
 
225
        public signal void Seeked(int64 Position);
 
226
        
 
227
        /* Methods: http://www.mpris.org/2.1/spec/Player_Node.html#methods */
 
228
 
 
229
        /**
 
230
         * Skips to the next track in the tracklist.
 
231
         * 
 
232
         * If there is no next track (and endless playback and track repeat are both off),
 
233
         * playback will be stopped. If playback is paused or stopped, it remains that way.
 
234
         */
 
235
        public void next(){
 
236
                this.frame.command("nextSong");
 
237
        }
 
238
        
 
239
        /***
 
240
         * Skips to the previous track in the tracklist.
 
241
         * 
 
242
         * If there is no previous track (and endless playback and track repeat are both off),
 
243
         * playback will be stopped. If playback is paused or stopped, it remains that way.
 
244
         */
 
245
        public void previous(){
 
246
                /* sometimes it's neede to send this command twice :-/ */
 
247
                this.frame.command("prevSong");
 
248
        }
 
249
        
 
250
        /**
 
251
         * Pauses playback.
 
252
         * 
 
253
         * If playback is already paused, this has no effect. Calling Play after this should
 
254
         * cause playback to start again from the same position. 
 
255
         */
 
256
        public void pause(){
 
257
                this.frame.command("pauseSong");
 
258
        }
 
259
        
 
260
        /**
 
261
         * Pauses playback.
 
262
         * If playback is already paused, resumes playback.
 
263
         * If playback is stopped, starts playback.
 
264
         */
 
265
        public void play_pause(){
 
266
                this.frame.command("playPause");
 
267
        }
 
268
        
 
269
        /**
 
270
         * Stops playback.
 
271
         * 
 
272
         * If playback is already stopped, this has no effect. Calling Play after this should
 
273
         * cause playback to start again from the beginning of the track. 
 
274
         */
 
275
        public void stop(){
 
276
                this.frame.command("pauseSong");
 
277
        }
 
278
        
 
279
        /**
 
280
         * Starts or resumes playback.
 
281
         * 
 
282
         * If already playing, this has no effect.
 
283
         * If there is no track to play, this has no effect.
 
284
         */
 
285
        public void play(){
 
286
                this.frame.command("playPause   ");
 
287
        }
 
288
        
 
289
        /**
 
290
         * Seeks forward in the current track by the specified number of microseconds.
 
291
         * 
 
292
         * A negative value seeks back. If this would mean seeking back further than the start
 
293
         * of the track, the position is set to 0. If the value passed in would mean seeking
 
294
         * beyond the end of the track, acts like a call to Next. If the CanSeek property
 
295
         * is false, this has no effect.
 
296
         * 
 
297
         * @param Offset The number of microseconds to seek forward.
 
298
         */
 
299
        public void seek(int64 Offset) {
 
300
                return;
 
301
        }
 
302
        
 
303
        /**
 
304
         * Sets the current track position in microseconds.
 
305
         * 
 
306
         * If the Position argument is less than 0, does nothing. 
 
307
         * If the Position argument is greater than the track length, does nothing.
 
308
         * If the CanSeek property is false, this has no effect. 
 
309
         * 
 
310
         * @param TrackId The currently playing track's identifier. If this does not match
 
311
         * the id of the currently-playing track, the call is ignored as "stale".
 
312
         * @param Position Track position in microseconds.This must be between 0 and <track_length>.
 
313
         */
 
314
        public void SetPosition(string dobj, int64 Position) {
 
315
        }
 
316
        
 
317
        /**
 
318
         * Not implemented.
 
319
         * @param Uri Uri of the track to load.
 
320
         */
 
321
        public void OpenUri(string Uri) {
 
322
                return;
 
323
        }
 
324
}
 
325