라즈베리파이 4 미디어 플레이어를 개발하기 위해 Qt와 GStreamer 로 아주 단간하게 테스트용도로 작성한 flac 오디오 재생 프로그램. (Qt Multimedia 가 아님) GStreamer의 Hello world 소스코드 일부를 수정하였고 flac 오디오 파일을 재생 시킨다..
#include <gst/gst.h>
class MediaPlayer::MediaPlayerImpl
{
public:
MediaPlayerImpl()
: pipeline(nullptr), source(nullptr), demuxer(nullptr), decoder(nullptr), conv(nullptr), sink(nullptr)
, bus(nullptr), bus_watch_id(0)
{
}
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
break;
}
default:
break;
}
return TRUE;
}
GstElement *pipeline, *source, *demuxer, *decoder, *conv, *sink;
GstBus *bus;
guint bus_watch_id;
};
MediaPlayer::MediaPlayer()
:pImpl(std::make_shared<MediaPlayerImpl>())
{
}
MediaPlayer::~MediaPlayer()
{
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pImpl->pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pImpl->pipeline));
g_source_remove (pImpl->bus_watch_id);
}
int MediaPlayer::init(int *argc, char **argv[])
{
/* Initialisation */
gst_init (argc, argv);
/* Create gstreamer elements */
pImpl->pipeline = gst_pipeline_new ("audio-player");
pImpl->source = gst_element_factory_make ("filesrc", "file-source");
pImpl->demuxer = gst_element_factory_make ("flacparse", "flacparse-demuxer");
pImpl->decoder = gst_element_factory_make ("flacdec", "flacdec-decoder");
pImpl->sink = gst_element_factory_make ("autoaudiosink", "audio-output");
if (!pImpl->pipeline || !pImpl->source || !pImpl->demuxer || !pImpl->decoder || !pImpl->sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
/* we add a message handler */
pImpl->bus = gst_pipeline_get_bus (GST_PIPELINE (pImpl->pipeline));
pImpl->bus_watch_id = gst_bus_add_watch (pImpl->bus, pImpl->bus_call, nullptr);
gst_object_unref (pImpl->bus);
/* we add all elements into the pipeline */
/* file-source | flacparse | flacdec-decoder | alsa-output */
gst_bin_add_many (GST_BIN (pImpl->pipeline),
pImpl->source, pImpl->demuxer, pImpl->decoder, pImpl->sink, NULL);
/* we link the elements together */
/* file-source -> flacparse ~> flacdec-decoder -> alsa-output */
gst_element_link_many (pImpl->source, pImpl->demuxer, pImpl->decoder, pImpl->sink, NULL);
return 0;
}
void MediaPlayer::setSourcePath(const QString &path)
{
/* we set the input filename to the source element */
g_object_set (G_OBJECT (pImpl->source), "location", path.toStdString().c_str(), NULL);
}
void MediaPlayer::play()
{
/* Set the pipeline to "playing" state*/
gst_element_set_state (pImpl->pipeline, GST_STATE_PLAYING);
}
void MediaPlayer::pause()
{
/* Set the pipeline to "pause" state*/
gst_element_set_state (pImpl->pipeline, GST_STATE_PAUSED);
}
void MediaPlayer::stop()
{
/* Set the pipeline to "stop" state*/
gst_element_set_state (pImpl->pipeline, GST_STATE_NULL);
}
예제의 GStreamer 파이프라인
FLAC Audio Playback
https://gstreamer.freedesktop.org/documentation/application-development/basics/helloworld.html