ocarina/gui/gst.cpp

159 lines
3.1 KiB
C++
Raw Normal View History

/*
* 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 <core/audio.h>
#include <gui/ocarina.h>
#include <gst/gst.h>
static GstBus *gst_bus;
static GstElement *gst_player;
static Gtk::Button *o_play;
static Gtk::Button *o_pause;
static bool gst_change_state(GstState state)
{
GstStateChangeReturn ret = gst_element_set_state(gst_player, state);
switch (ret) {
case GST_STATE_CHANGE_SUCCESS:
case GST_STATE_CHANGE_ASYNC:
return true;
default:
return false;
}
}
class GSTDriver : public AudioDriver
{
public:
void load(Track *track)
{
gchar *uri = gst_filename_to_uri(track->path().c_str(), NULL);
gst_change_state(GST_STATE_NULL);
g_object_set(G_OBJECT(gst_player), "uri", uri, NULL);
g_free(uri);
on_track_loaded(track);
}
void play()
{
if (gst_change_state(GST_STATE_PLAYING)) {
o_play->hide();
o_pause->show();
}
}
void pause()
{
if (gst_change_state(GST_STATE_PAUSED)) {
o_play->show();
o_pause->hide();
}
}
bool is_playing()
{
GstState state;
gst_element_get_state(gst_player,
&state,
NULL,
GST_CLOCK_TIME_NONE);
return state == GST_STATE_PLAYING;
}
void seek_to(long offset)
{
gst_element_seek_simple(gst_player,
GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH,
offset);
}
long position()
{
long position;
if (gst_element_query_position(gst_player,
GST_FORMAT_TIME,
&position))
return position;
return 0;
}
long duration()
{
long duration;
if (gst_element_query_duration(gst_player,
GST_FORMAT_TIME,
&duration))
return duration;
return 0;
}
};
static GSTDriver *gst_driver;
static void parse_gst_error(GstMessage *error)
{
GError *err;
Track *track = audio :: current_track();
gst_message_parse_error(error, &err, NULL);
if (track)
g_print("Error playing file: %s\n", track->path().c_str());
g_print("Error: %s\n", err->message);
g_error_free(err);
}
static gboolean on_gst_message(GstBus *bus, GstMessage *message, gpointer data)
{
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR:
parse_gst_error(message);
audio :: next();
break;
case GST_MESSAGE_EOS:
gst_driver->eos();
on_pause_count_changed(audio :: pause_enabled(),
audio :: pause_count());
break;
default:
break;
}
return TRUE;
}
void init_gst(int *argc, char ***argv)
{
gst_init(argc, argv);
gst_player = gst_element_factory_make("playbin", "ocarina_player");
gst_bus = gst_pipeline_get_bus(GST_PIPELINE(gst_player));
gst_driver = new GSTDriver();
o_play = lib :: get_widget<Gtk::Button>("o_play");
o_pause = lib :: get_widget<Gtk::Button>("o_pause");
gst_bus_add_watch(gst_bus, on_gst_message, NULL);
o_play->signal_clicked().connect(sigc::ptr_fun(audio :: play));
o_pause->signal_clicked().connect(sigc::ptr_fun(audio :: pause));
}
void quit_gst()
{
delete gst_driver;
gst_change_state(GST_STATE_NULL);
gst_deinit();
}