~audio-recorder/audio-recorder/trunk

« back to all changes in this revision

Viewing changes to src/dbus-rhythmbox.c

  • Committer: Osmo Antero
  • Date: 2012-04-18 19:22:01 UTC
  • Revision ID: osmoma@gmail.com-20120418192201-ejjs6ikv7o4aznbi
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) Linux community.
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Library General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Library General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Library General Public
15
 
 * License along with this library; if not, write to the
16
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
 * Boston, MA 02111-1307, USA.
18
 
 */
19
 
#include "dbus-player.h"
20
 
#include "dbus-mpris.h"
21
 
#include "dbus-rhythmbox.h"
22
 
#include "log.h"
23
 
#include "support.h"
24
 
#include "utility.h"
25
 
 
26
 
void rhythmbox_player_track_changed(MediaPlayerRec *player) {
27
 
    // Called when the track changes
28
 
 
29
 
    // Re-read all player data
30
 
    rhythmbox_get_info(player);
31
 
 
32
 
    TrackInfo *tr = &player->track;
33
 
    tr->status = PLAYER_STATUS_STOPPED;
34
 
 
35
 
    // Print debug info
36
 
    // dbus_player_debug_print(player);
37
 
 
38
 
    // Process data
39
 
    dbus_player_process_data(player);
40
 
}
41
 
 
42
 
void rhythmbox_player_status_changed(MediaPlayerRec *player) {
43
 
    // Called when player's status changes
44
 
 
45
 
    // Re-read all player data
46
 
    rhythmbox_get_info(player);
47
 
 
48
 
    // Print debug info
49
 
    // dbus_player_debug_print(player);
50
 
 
51
 
    // Process data
52
 
    dbus_player_process_data(player);
53
 
}
54
 
 
55
 
void rhythmbox_get_app_name(MediaPlayerRec *player) {
56
 
    // Name of the RhythmBox Media Player.
57
 
    player->app_name = g_strdup(_("RhythmBox Media Player"));
58
 
}
59
 
 
60
 
void rhythmbox_track_signal_cb(DBusGProxy *player_proxy, gpointer data, MediaPlayerRec *player) {
61
 
    // Track changed signal from RhythmBox
62
 
 
63
 
    gchar *track = (gchar*)data;
64
 
    if (track) {
65
 
        /*suppress unused variable msg*/
66
 
    }
67
 
 
68
 
    LOG_PLAYER("rhythmbox_track_signal_cb: %s (%s), TrackChanged: %s\n", player->app_name, player->service_name, track);
69
 
 
70
 
    rhythmbox_player_track_changed(player);
71
 
}
72
 
 
73
 
void rhythmbox_status_signal_cb(DBusGProxy *player_proxy, gpointer data, MediaPlayerRec *player) {
74
 
    // Status signal from RhythmBox
75
 
 
76
 
    gboolean status = (gint)(long)data;
77
 
    if (status) {
78
 
        /*suppress unused variable msg*/
79
 
    }
80
 
    // Pause=0
81
 
    // Playing=1
82
 
 
83
 
    LOG_PLAYER("rhythmbox_status_signal_cb: %s (%s) Status: %d\n", player->app_name, player->service_name, status);
84
 
 
85
 
    rhythmbox_player_status_changed(player);
86
 
}
87
 
 
88
 
gboolean rhythmbox_check_proxy(MediaPlayerRec *player) {
89
 
    // Check and set proxy
90
 
    if (!player) return FALSE;
91
 
 
92
 
    if (!player->proxy) {
93
 
        DBusGConnection *dbus_conn = dbus_player_connect_to_dbus();
94
 
 
95
 
        player->proxy = dbus_g_proxy_new_for_name(dbus_conn,
96
 
                        player->service_name,
97
 
                        "/org/gnome/Rhythmbox/Player",
98
 
                        "org.gnome.Rhythmbox.Player");
99
 
    }
100
 
 
101
 
    if (!player->proxy) {
102
 
        LOG_ERROR("rhythmbox_check_proxy: Cannot create DBus proxy for RhythmBox.\n");
103
 
    }
104
 
 
105
 
    return (player->proxy != NULL);
106
 
}
107
 
 
108
 
void rhythmbox_set_signals(gpointer player_rec, gboolean connect) {
109
 
    // Connect/disconnect signals
110
 
 
111
 
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
112
 
    if (!player) return;
113
 
 
114
 
    if (!player->proxy) {
115
 
 
116
 
        // Check/set proxy
117
 
        if (!rhythmbox_check_proxy(player)) return;
118
 
 
119
 
        // Register arguments.
120
 
        dbus_g_proxy_add_signal(player->proxy, "playingUriChanged", G_TYPE_STRING, G_TYPE_INVALID);
121
 
        dbus_g_proxy_add_signal(player->proxy, "playingChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
122
 
    }
123
 
 
124
 
    if (!rhythmbox_check_proxy(player)) return;
125
 
 
126
 
    if (connect) {
127
 
        // Connect signals
128
 
        dbus_g_proxy_connect_signal(player->proxy, "playingUriChanged", G_CALLBACK(rhythmbox_track_signal_cb), (gpointer)player, NULL);
129
 
        dbus_g_proxy_connect_signal(player->proxy, "playingChanged", G_CALLBACK(rhythmbox_status_signal_cb), (gpointer)player, NULL);
130
 
    } else  {
131
 
        // Disconnect signals
132
 
        dbus_g_proxy_disconnect_signal(player->proxy, "playingUriChanged", G_CALLBACK(rhythmbox_track_signal_cb), (gpointer)player);
133
 
        dbus_g_proxy_disconnect_signal(player->proxy, "playingChanged", G_CALLBACK(rhythmbox_status_signal_cb), (gpointer)player);
134
 
    }
135
 
}
136
 
 
137
 
gboolean get_hash_str(GHashTable *table, gchar *key, gchar *dest) {
138
 
    dest[0] = '\0';
139
 
 
140
 
    GValue* value = (GValue*)g_hash_table_lookup(table, key);
141
 
 
142
 
    if (value && G_VALUE_HOLDS_STRING(value)) {
143
 
        str_copy(dest, (gchar*)g_value_get_string(value), MPRIS_STRLEN-1);
144
 
        return TRUE;
145
 
    }
146
 
 
147
 
    return FALSE;
148
 
}
149
 
 
150
 
guint get_hash_uint(GHashTable *table, gchar *key) {
151
 
    guint ret = 0;
152
 
    GValue* value = (GValue*) g_hash_table_lookup(table, key);
153
 
 
154
 
    if (G_VALUE_HOLDS_UINT(value)) {
155
 
        ret = g_value_get_uint(value);
156
 
    }
157
 
 
158
 
    return ret;
159
 
}
160
 
 
161
 
void rhythmbox_get_info(gpointer player_rec) {
162
 
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
163
 
    TrackInfo *tr = &player->track;
164
 
 
165
 
    tr->status = PLAYER_STATUS_STOPPED;
166
 
 
167
 
    // Check/set proxy
168
 
    if (!rhythmbox_check_proxy(player)) return;
169
 
 
170
 
    DBusGProxy *shell_proxy = NULL;
171
 
 
172
 
    // Is this player running/active?
173
 
    player->active = mpris_service_is_running_by_name(player->service_name);
174
 
    if (!player->active) {
175
 
        tr->status = PLAYER_STATUS_CLOSED;
176
 
        goto LBL_1;
177
 
    }
178
 
 
179
 
    DBusGConnection *dbus_conn = dbus_player_connect_to_dbus();
180
 
 
181
 
    GError *error = NULL;
182
 
    shell_proxy = dbus_g_proxy_new_for_name(dbus_conn,
183
 
                                            "org.gnome.Rhythmbox",
184
 
                                            "/org/gnome/Rhythmbox/Shell",
185
 
                                            "org.gnome.Rhythmbox.Shell");
186
 
 
187
 
    gboolean playing;
188
 
    if (!dbus_g_proxy_call_with_timeout(player->proxy, "getPlaying", DBUS_MPRIS_TIMEOUT, &error,
189
 
                                        G_TYPE_INVALID,
190
 
                                        G_TYPE_BOOLEAN, &playing,
191
 
                                        G_TYPE_INVALID)) {
192
 
 
193
 
        LOG_ERROR("rhythmbox_get_info: Failed to get playing state from RhythmBox. %s.", error ? error->message : "");
194
 
        tr->status = PLAYER_STATUS_STOPPED;
195
 
 
196
 
        if (error)
197
 
            g_error_free(error);
198
 
 
199
 
        goto LBL_1;
200
 
    }
201
 
 
202
 
    gchar *uri = NULL;
203
 
    if (!dbus_g_proxy_call_with_timeout(player->proxy, "getPlayingUri", DBUS_MPRIS_TIMEOUT, &error,
204
 
                                        G_TYPE_INVALID,
205
 
                                        G_TYPE_STRING, &uri,
206
 
                                        G_TYPE_INVALID)) {
207
 
        LOG_ERROR("rhythmbox_get_info: Failed to get song uri from RhythmBox. %s.", error ? error->message : "");
208
 
 
209
 
        if (error)
210
 
            g_error_free(error);
211
 
 
212
 
        goto LBL_1;
213
 
    }
214
 
 
215
 
    GHashTable *table = NULL;
216
 
    if (!dbus_g_proxy_call_with_timeout(shell_proxy, "getSongProperties", DBUS_MPRIS_TIMEOUT, &error, G_TYPE_STRING, uri, G_TYPE_INVALID,
217
 
                                        dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &table, G_TYPE_INVALID)) {
218
 
 
219
 
        if (!playing) {
220
 
            tr->status = PLAYER_STATUS_STOPPED;
221
 
        }
222
 
 
223
 
        if (error)
224
 
            g_error_free(error);
225
 
 
226
 
        goto LBL_1;
227
 
    }
228
 
 
229
 
    g_free(uri);
230
 
 
231
 
    if (playing)
232
 
        tr->status = PLAYER_STATUS_PLAYING;
233
 
    else
234
 
        tr->status = PLAYER_STATUS_PAUSED;
235
 
 
236
 
    // Check if stream title is nonempty, if so, take title
237
 
    if (!get_hash_str(table, "rb:stream-song-title", tr->track)) {
238
 
        get_hash_str(table, "title", tr->track);
239
 
    }
240
 
 
241
 
    get_hash_str(table, "artist", tr->artist);
242
 
    get_hash_str(table, "album", tr->album);
243
 
 
244
 
    tr->total_secs = get_hash_uint(table, "duration");
245
 
 
246
 
    g_hash_table_destroy(table);
247
 
 
248
 
    if (!dbus_g_proxy_call_with_timeout(player->proxy, "getElapsed", DBUS_MPRIS_TIMEOUT, &error,
249
 
                                        G_TYPE_INVALID,
250
 
                                        G_TYPE_UINT, &tr->current_secs,
251
 
                                        G_TYPE_INVALID)) {
252
 
 
253
 
        LOG_ERROR("rhythmbox_get_info: Failed to get elapsed time from RhythmBox. %s.", error ? error->message : "");
254
 
 
255
 
        if (error)
256
 
            g_error_free(error);
257
 
    }
258
 
 
259
 
LBL_1:
260
 
    // Unref proxy
261
 
    if (shell_proxy)
262
 
        g_object_unref(shell_proxy);
263
 
 
264
 
}
265
 
 
266
 
void rhythmbox_start_app(gpointer player_rec) {
267
 
    // Function to start RhythmBox
268
 
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
269
 
 
270
 
    LOG_PLAYER("rhythmbox_start_app: %s\n", player->app_name);
271
 
 
272
 
    if (!rhythmbox_check_proxy(player)) return;
273
 
 
274
 
    // Start player
275
 
    dbus_g_proxy_call_no_reply(player->proxy, "Play", G_TYPE_INVALID);
276
 
}
277