以下代码来自应用开发文档。编译下
gcc -Wall $(pkg-config --cflags --libs gstreamer-0.10) helloworld.c
找不到ogg音乐文件唉,这样子用gst-launch转换一下。
gst-launch-0.10 filesrc location=./qhc.mp3 ! mad ! audioconvert ! vorbisenc ! oggmux ! filesink location=./qhc.ogg
./a.out ~/qhc.ogg
开始播放了,效果很好啊,呵呵。
关于
g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), decoder);
是为了信号“pad-added”产生时,调用函数on_pad_added.
字符串"pad-added"不是乱写的,看GstElement定义的信号如下:
"no-more-pads " : Run Last "pad-added " : Run Last "pad-removed " : Run Last
并且,文档中对某个信号处理函数的形式也有具体定义,"pad-added"信号的
回调函数的形式定义如下:
The "pad-added"
signal
void user_function (GstElement *gstelement, GstPad *new_pad, gpointer user_data) : Run Last
a new GstPad has been added to the element.
| the object which received the signal |
| the pad that has been added |
| user data set when the signal handler was connected. |
看看,这个程序中,on_pad_added的定义,必须遵从上述。
#include <gst/gst.h> #include <glib.h> static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("End of stream/n"); g_main_loop_quit (loop); 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); g_main_loop_quit (loop); break; } default: break; } return TRUE; } static void on_pad_added (GstElement *element, GstPad *pad, gpointer data) { GstPad *sinkpad; GstElement *decoder = (GstElement *) data; /* We can now link this pad with the vorbis-decoder sink pad */ g_print ("Dynamic pad created, linking demuxer/decoder/n"); sinkpad = gst_element_get_static_pad (decoder, "sink"); gst_pad_link (pad, sinkpad); gst_object_unref (sinkpad); } int main (int argc, char *argv[]) { GMainLoop *loop; GstElement *pipeline, *source, *demuxer, *decoder, *conv, *sink; GstBus *bus; /* Initialisation */ gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); /* Check input arguments */ if (argc != 2) { g_printerr ("Usage: %s <Ogg/Vorbis filename>/n", argv[0]); return -1; } /* Create gstreamer elements */ pipeline = gst_pipeline_new ("audio-player"); source = gst_element_factory_make ("filesrc", "file-source"); demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer"); decoder = gst_element_factory_make ("vorbisdec", "vorbis-decoder"); conv = gst_element_factory_make ("audioconvert", "converter"); sink = gst_element_factory_make ("autoaudiosink", "audio-output"); if (!pipeline || !source || !demuxer || !decoder || !conv || !sink) { g_printerr ("One element could not be created. Exiting./n"); return -1; } /* Set up the pipeline */ /* we set the input filename to the source element */ g_object_set (G_OBJECT (source), "location", argv[1], NULL); /* we add a message handler */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, bus_call, loop); gst_object_unref (bus); /* we add all elements into the pipeline */ /* file-source | ogg-demuxer | vorbis-decoder | converter | alsa-output */ gst_bin_add_many (GST_BIN (pipeline), source, demuxer, decoder, conv, sink, NULL); /* we link the elements together */ /* file-source -> ogg-demuxer ~> vorbis-decoder -> converter -> alsa-output */ gst_element_link (source, demuxer); gst_element_link_many (decoder, conv, sink, NULL); g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), decoder); /* note that the demuxer will be linked to the decoder dynamically. The reason is that Ogg may contain various streams (for example audio and video). The source pad(s) will be created at run time, by the demuxer when it detects the amount and nature of streams. Therefore we connect a callback function which will be executed when the "pad-added" is emitted.*/ /* Set the pipeline to "playing" state*/ g_print ("Now playing: %s/n", argv[1]); gst_element_set_state (pipeline, GST_STATE_PLAYING); /* Iterate */ g_print ("Running.../n"); g_main_loop_run (loop); /* Out of the main loop, clean up nicely */ g_print ("Returned, stopping playback/n"); gst_element_set_state (pipeline, GST_STATE_NULL); g_print ("Deleting pipeline/n"); gst_object_unref (GST_OBJECT (pipeline)); return 0; }