/* * Copyright 2014 (c) Anna Schumaker. * * The gst_init() function parses command line options passed to Ocarina * through argv. Use the command `gst-inspect-1.0 --help-gst` to find * what options are supported. */ #include extern "C" { #include #include } #include #include static GstBus *gst_bus; static Gtk::Button *o_next; static Gtk::Button *o_pause; static Gtk::Button *o_play; static Gtk::Button *o_prev; static Gtk::Scale *o_seek; static Gtk::Button *o_stop; static Gtk::SpinButton *o_count; static Gtk::CheckButton *o_enabled; static Gtk::Label *o_album; static Gtk::Label *o_artist; static Gtk::Label *o_duration; static Gtk::Label *o_position; static Gtk::Label *o_title; static Glib::RefPtr o_progress; static void set_markup(Gtk::Label *label, const std::string &size, const std::string &text) { label->set_markup("" + Glib::Markup::escape_text(text) + ""); } static void on_pause() { o_play->show(); o_pause->hide(); } static void on_load(struct track *track, GstState state) { gchar *str = g_strdup_printf("From: %s", track->tr_album->al_name); set_markup(o_album, "x-large", str); g_free(str); str = g_strdup_printf("By: %s", track->tr_artist->ar_name); set_markup(o_artist, "x-large", str); g_free(str); set_markup(o_title, "xx-large", track->tr_title); str = string_sec2str(track->tr_length); o_duration->set_text(str); g_free(str); plist :: track_loaded(track); if (state != GST_STATE_PLAYING) on_pause(); } class GSTDriver : public AudioDriver { public: bool is_playing() { GstState state; gst_element_get_state(audio_get_player(), &state, NULL, GST_CLOCK_TIME_NONE); return state == GST_STATE_PLAYING; } int64_t position() { int64_t position; if (gst_element_query_position(audio_get_player(), GST_FORMAT_TIME, &position)) return position; return 0; } int64_t duration() { int64_t duration; if (gst_element_query_duration(audio_get_player(), GST_FORMAT_TIME, &duration)) return duration; return 0; } }; static GSTDriver *gst_driver; struct audio_ops audio_ops = { on_load, }; static int parse_gst_error(GstMessage *error) { GError *err; struct track *track = audio :: current_track(); gchar *path; int ret = 0; gst_message_parse_error(error, &err, NULL); if (track) { path = track_path(track); g_print("Error playing file: %s\n", path); ret = collection_check_library(track->tr_library); g_free(path); } g_print("Error: %s\n", err->message); g_error_free(err); return ret; } static gboolean on_gst_message(GstBus *bus, GstMessage *message, gpointer data) { switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_ERROR: if (parse_gst_error(message) < 0) break; audio :: next(); gst :: play(); break; case GST_MESSAGE_EOS: gst_driver->eos(); o_count->set_value(audio :: pause_count()); o_enabled->set_active(audio :: pause_enabled()); break; default: break; } return TRUE; } static bool on_seek(Gtk::ScrollType type, double value) { audio_seek(value); return true; } static void on_pause_count() { o_enabled->set_active(true); audio :: pause_after(true, o_count->get_value()); } static void on_pause_enabled() { audio :: pause_after(o_enabled->get_active(), o_count->get_value()); } static bool on_timeout() { gchar *pos = string_sec2str(audio :: position() / GST_SECOND); o_progress->set_upper(audio :: duration()); o_progress->set_value(audio :: position()); o_position->set_text(pos); g_free(pos); return true; } void gst :: play() { if (audio_play()) { o_play->hide(); o_pause->show(); } } void gst :: pause() { if (audio_pause()) { on_pause(); } } void gst :: next() { audio :: next(); gst :: play(); } void gst :: toggle() { if (gst_driver->is_playing()) gst :: pause(); else gst :: play(); } void gst :: init_pre() { gst_driver = new GSTDriver(); o_next = gui :: get_widget("o_next"); o_pause = gui :: get_widget("o_pause"); o_play = gui :: get_widget("o_play"); o_prev = gui :: get_widget("o_prev"); o_seek = gui :: get_widget("o_seek"); o_stop = gui :: get_widget("o_stop"); o_count = gui :: get_widget("o_pause_count"); o_enabled = gui :: get_widget("o_pause_enabled"); o_album = gui :: get_widget("o_album"); o_artist = gui :: get_widget("o_artist"); o_duration = gui :: get_widget("o_duration"); o_position = gui :: get_widget("o_position"); o_title = gui :: get_widget("o_title"); o_progress = gui :: get_object("o_progress"); o_next->signal_clicked().connect(sigc::ptr_fun(next)); o_pause->signal_clicked().connect(sigc::ptr_fun(gst :: pause)); o_play->signal_clicked().connect(sigc::ptr_fun(gst :: play)); o_prev->signal_clicked().connect(sigc::ptr_fun(audio :: prev)); o_seek->signal_change_value().connect(sigc::ptr_fun(on_seek)); o_stop->signal_clicked().connect(sigc::ptr_fun(audio :: stop)); o_count->signal_changed().connect(sigc::ptr_fun(on_pause_count)); o_enabled->signal_toggled().connect(sigc::ptr_fun(on_pause_enabled)); } void gst :: init() { gst_bus = gst_pipeline_get_bus(GST_PIPELINE(audio_get_player())); gst_bus_add_watch(gst_bus, on_gst_message, NULL); Glib :: signal_timeout().connect(sigc::ptr_fun(on_timeout), 500); } void gst :: quit() { delete gst_driver; }