2
* player.c - Simple media player based on GStreamer
4
* Copyright (C) 2007-2008 Johannes H. Jensen <joh@pseudoberries.com>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
* Johannes H. Jensen <joh@pseudoberries.com>
29
* Create a new media player.
31
* @uri The file to play.
32
* @loop Wether to loop or not.
33
* @state_callback An optional #MediaPlayerStateChangeCallback which will be
34
* notified when the state of the player changes.
35
* @data Data for the state_callback
36
* @error_handler An optional #MediaPlayerErrorHandler which will be notified
38
* @error_data Data for the error_handler.
41
media_player_new (const gchar *uri, gboolean loop,
42
MediaPlayerStateChangeCallback state_callback, gpointer data,
43
MediaPlayerErrorHandler error_handler, gpointer error_data)
46
GstElement *audiosink, *videosink;
49
player = g_new (MediaPlayer, 1);
52
player->state = MEDIA_PLAYER_STOPPED;
55
player->state_changed = state_callback;
56
player->state_changed_data = data;
57
player->error_handler = error_handler;
58
player->error_handler_data = error_data;
60
// Initialize GStreamer
61
gst_init (NULL, NULL);
64
player->player = gst_element_factory_make ("playbin", "player");
65
audiosink = gst_element_factory_make ("gconfaudiosink", "player-audiosink");
66
videosink = gst_element_factory_make ("gconfvideosink", "player-videosink");
68
if (!player->player || !audiosink || !videosink) {
69
g_critical ("Could not create player.");
74
g_object_set (player->player,
76
"audio-sink", audiosink,
77
"video-sink", videosink,
84
* Free a media player.
87
media_player_free (MediaPlayer *player)
90
gst_object_unref (GST_OBJECT (player->player));
96
* Set the uri of player.
99
media_player_set_uri (MediaPlayer *player, const gchar *uri)
101
g_object_set (player->player, "uri", uri, NULL);
105
* Get the uri of player.
110
media_player_get_uri (MediaPlayer *player)
114
g_object_get (player->player, "uri", &uri, NULL);
120
* Set media player state.
123
media_player_set_state (MediaPlayer *player, MediaPlayerState state)
125
MediaPlayerState old = player->state;
127
player->state = state;
129
// Notify state change handler
130
if (old != state && player->state_changed)
131
player->state_changed(player, player->state, player->state_changed_data);
136
* Check for errors & call error handler
139
media_player_bus_check_errors (MediaPlayer *player, GstMessage *message)
141
// g_debug ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
143
switch (GST_MESSAGE_TYPE (message)) {
144
case GST_MESSAGE_ERROR: {
148
gst_message_parse_error (message, &err, &debug);
150
if (player->error_handler)
151
player->error_handler (player, err, player->error_handler_data);
171
media_player_bus_cb (GstBus *bus,
175
// g_debug ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
177
if (media_player_bus_check_errors (player, message)) {
178
if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS) {
179
// End of Stream, do we loop?
181
media_player_stop (player);
186
gst_element_set_state (player->player, GST_STATE_READY);
187
gst_element_set_state (player->player, GST_STATE_PLAYING);
189
media_player_set_state (player, MEDIA_PLAYER_PLAYING);
197
media_player_stop (player);
206
media_player_start (MediaPlayer *player)
210
// Attach bus watcher
211
bus = gst_pipeline_get_bus (GST_PIPELINE (player->player));
212
player->watch_id = gst_bus_add_watch (bus, (GstBusFunc) media_player_bus_cb, player);
213
gst_object_unref (bus);
215
gst_element_set_state (player->player, GST_STATE_PLAYING);
216
media_player_set_state (player, MEDIA_PLAYER_PLAYING);
223
media_player_stop (MediaPlayer *player)
225
if (player->watch_id) {
226
g_source_remove (player->watch_id);
228
player->watch_id = 0;
231
if (player->player != NULL) {
232
gst_element_set_state (player->player, GST_STATE_NULL);
235
media_player_set_state (player, MEDIA_PLAYER_STOPPED);