Archive / / / / PlaybackManager.cc
2008-10-22 02:23:35 UTC
previous next
/* Echo Media Player * Copyright (C) 2008 Shane O'Connell * * [ The original file includes a copyright header in this location describing * the file as being released under the terms of the GNU General Public * License. It has been removed in order to display the file as part of the * archive. ] */ #include "PlaybackManager.h" #include <giomm.h> #include <gst/gst.h> #include <list> #include <iostream> #include <cassert> #include <cstdlib> using namespace std; sigc::signal<void, PlaySourceRef, int, bool> PlaybackManager::_signal_track_started; sigc::signal<void, PlaySourceRef, int, bool> PlaybackManager::_signal_track_stopped; static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer data); GstElement* gst_player; PlaySourceRef current_playlist; int current_index; // TODO we need to update current_index when tracks are inserted/removed in the playlist ShuffleType current_shuffle; void PlaybackManager::init_sound(int *argc, char **argv[]) { gst_init(argc, argv); // TODO use gconfsink so that we use users settings gst_player = gst_element_factory_make("playbin", "player"); GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE (gst_player)); gst_bus_add_watch(bus, bus_callback, NULL); gst_object_unref(bus); } gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); cout << "Gstreamer error: " << err->message << endl; g_error_free (err); g_free (debug); break; case GST_MESSAGE_EOS: PlaybackManager::next(); break; default: break; } return TRUE; } void PlaybackManager::play(PlaySourceRef playlist, int index) { assert(index >= 0); assert(index < playlist->get_num_tracks()); gst_element_set_state(gst_player, GST_STATE_READY); if (current_playlist) PlaybackManager::signal_track_stopped().emit(current_playlist, current_index, false); current_playlist = playlist; current_index = index; g_object_set(G_OBJECT(gst_player), "uri", playlist->get_track(index)->get_uri().c_str(), NULL); gst_element_set_state(gst_player, GST_STATE_PLAYING); PlaybackManager::signal_track_started().emit(current_playlist, current_index, false); } void PlaybackManager::next() { assert(current_playlist); if (GST_STATE(gst_player) != GST_STATE_READY) gst_element_set_state(gst_player, GST_STATE_READY); if (current_playlist) PlaybackManager::signal_track_stopped().emit(current_playlist, current_index, false); switch (current_shuffle) { case SHUFFLE_NONE: current_index++; break; default: current_index = rand() % current_playlist->get_num_tracks(); break; } if (current_index < current_playlist->get_num_tracks()) { g_object_set(G_OBJECT(gst_player), "uri", current_playlist->get_track(current_index)->get_uri().c_str(), NULL); gst_element_set_state(gst_player, GST_STATE_PLAYING); PlaybackManager::signal_track_started().emit(current_playlist, current_index, false); } else current_playlist.reset(); } void PlaybackManager::prev() { assert(current_playlist); if (GST_STATE(gst_player) != GST_STATE_READY) gst_element_set_state(gst_player, GST_STATE_READY); if (current_playlist) PlaybackManager::signal_track_stopped().emit(current_playlist, current_index, false); current_index--; if (current_index >= 0) { g_object_set(G_OBJECT(gst_player), "uri", current_playlist->get_track(current_index)->get_uri().c_str(), NULL); gst_element_set_state(gst_player, GST_STATE_PLAYING); PlaybackManager::signal_track_started().emit(current_playlist, current_index, false); } } void PlaybackManager::stop() { gst_element_set_state(gst_player, GST_STATE_READY); PlaybackManager::signal_track_started().emit(current_playlist, current_index, false); current_playlist.reset(); } void PlaybackManager::pause() { assert(current_playlist); assert(!is_paused()); gst_element_set_state(gst_player, GST_STATE_PAUSED); PlaybackManager::signal_track_stopped().emit(current_playlist, current_index, true); } void PlaybackManager::unpause() { assert(current_playlist); assert(is_paused()); gst_element_set_state(gst_player, GST_STATE_PLAYING); PlaybackManager::signal_track_started().emit(current_playlist, current_index, true); } bool PlaybackManager::is_paused() { //GstState state; //gst_element_get_state(gst_player, &state, NULL, GST_CLOCK_TIME_NONE); //return (state == GST_STATE_PAUSED); return (GST_STATE(gst_player) == GST_STATE_PAUSED); } int PlaybackManager::get_track_length() { GstFormat format = GST_FORMAT_TIME; long long length; if (gst_element_query_duration(gst_player, &format, &length) == TRUE) { if (format == GST_FORMAT_TIME) { return (length / 1000000); // return in ms } } return 0; } int PlaybackManager::get_track_position() { GstFormat format = GST_FORMAT_TIME; long long position; if (gst_element_query_position(gst_player, &format, &position) == TRUE) { if (format == GST_FORMAT_TIME) { return (position / 1000000); // return in ms } } return 0; } PlaySourceRef PlaybackManager::get_playing_source() { return current_playlist; } int PlaybackManager::get_playing_index() { return current_index; } void PlaybackManager::set_shuffle(ShuffleType type) { current_shuffle = type; }