// Copyright (c) 2011 Bryan Schumaker. #include #include #include #include using namespace std; static GstElement *player = NULL; static GstFormat fmt_time = GST_FORMAT_TIME; static GstState cur_state = GST_STATE_READY; static void notify_state_change(GstState state) { if (state == GST_STATE_PLAYING) libsaria::notify(PLAYING, NULL); else if (state == GST_STATE_PAUSED) libsaria::notify(PAUSED, NULL); } static bool change_state(GstState new_state) { GstStateChangeReturn ret; ret = gst_element_set_state(GST_ELEMENT(player), new_state); switch(ret) { case GST_STATE_CHANGE_SUCCESS: case GST_STATE_CHANGE_ASYNC: cur_state = new_state; notify_state_change(cur_state); return true; default: return false; } } void load_file(GstElement *playbin, string file, GstState state) { gchar *escaped; if (file == "" || !libsaria::exists(file)) return; println("Loading file: " + file); escaped = gst_filename_to_uri(file.c_str(), NULL); /* Set pipeline to the requested state */ change_state(GST_STATE_READY); g_object_set(G_OBJECT(playbin), "uri", escaped, NULL); change_state(state); g_free(escaped); } static string to_string(gint64 time) { stringstream stream; int minutes, seconds; if (time == 0) return ""; time = time / GST_SECOND; minutes = time / 60; seconds = time - (minutes * 60); stream << minutes << ":"; if (seconds < 10) stream << "0"; stream << seconds; return stream.str(); } static void parse_error(GstMessage *error) { GError *err; gchar *debug; gst_message_parse_error(error, &err, &debug); g_print("Error: %s\n", err->message); g_error_free(err); g_free(debug); } static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data) { switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_ERROR: parse_error(message); case GST_MESSAGE_EOS: libsaria::deck::next(); default: break; } return TRUE; } namespace libsaria { void audio::play() { change_state(GST_STATE_PLAYING); } void audio::pause() { change_state(GST_STATE_PAUSED); } void audio::toggle_play() { if (cur_state == GST_STATE_PLAYING) pause(); else play(); } GstState audio::get_state() { return cur_state; } void audio::stop() { pause(); seek_to(0); } void audio::load(string file, bool play) { GstState state = GST_STATE_PLAYING; if (!play) state = GST_STATE_PAUSED; load_file(player, file, state); } /* Seek to this many seconds into the song */ void audio::seek_to(double pos) { gst_element_seek_simple(GST_ELEMENT(player), GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, pos); } gint64 audio::duration() { gint64 duration; if (!gst_element_query_duration(player, &fmt_time, &duration)) return 0; if (duration < 0) duration = 0; return duration; } gint64 audio::position() { gint64 position; if (!gst_element_query_position(player, &fmt_time, &position)) return 0; return position; } string audio::posstr() { return to_string(position()); } bool audio::played() { return position() > ((duration() * 3) / 4); } void audio::init(int argc, char **argv) { static GstBus *bus; println("Initializing libsaria audio"); gst_init(&argc, &argv); player = gst_element_factory_make("playbin2", "player"); bus = gst_pipeline_get_bus(GST_PIPELINE(player)); gst_bus_add_watch(bus, on_message, NULL); } void audio::quit() { gst_deinit(); } };