內容轉自 http://phinecos.cnblogs.com/
本文介紹如何使用GStreamer 編寫一個簡單的MP3播放器。
1,需要使用mad解碼插件,因此需要先安裝gstreamer0.10-plugins-ugly
2,編寫mp3播放器
下面來看看如何利用GStreamer框架提供的組件,來實現一個簡單的MP3播放器。數據源元件負責從磁盤上讀取數據,過濾器元件負責對數據進行解碼,而接受器元件則負責將解碼後的數據寫入聲卡。
如果想要在程序中應用GStreamer提供的各種功能,首先必須在主函數中調用gst_init()來完成相應的初始化工作,以便將用戶從命令行輸入的參數傳遞給GStreamer函數庫。一個典型的GStreamer應用程序的初始化如下所示:
int main (int argc, char *argv[])
{
gst_init (&argc, &argv);
/* */
}
接下去需要創建三個元件並連接成管道,由於所有GStreamer元件都具有相同的基類GstElement,因此能夠採用如下方式進行定義:
管道在GStreamer框架中是用來容納和管理元件的,下面的代碼將創建一條名爲pipeline的新管道:
pipeline = gst_pipeline_new ("pipeline");
數據源元件負責從磁盤文件中讀取數據,它具有名爲location的屬性,用來指明文件在磁盤上的位置。使用標準的GObject屬性機制可以爲元件設置相應的屬性:
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
過濾器元件負責完成對MP3格式的數據進行解碼,最簡單的辦法是安裝mad這一插件,藉助它來完成相應的解碼工作:
decoder = gst_element_factory_make ("mad", "decoder");
接收器元件負責將解碼後的數據利用聲卡播放出來:
audiosink = gst_element_factory_make ("audiosink", "play_audio")
已經創建好的三個元件需要全部添加到管道中,並按順序連接起來:
gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, audiosink, NULL);
/* 通過襯墊連接元件 */
gst_element_link_many (filesrc, decoder, audiosink, NULL);
所有準備工作都做好之後,就可以通過將管道的狀態切換到PLAYING狀態,來啓動整個管道的數據處理流程:
gst_element_set_state (pipeline, GST_STATE_PLAYING);
這裏加入一個消息處理函數bus_call來監視產生的消息
gst_element_set_state (pipeline, GST_STATE_NULL);
/* 釋放資源 */
gst_object_unref (GST_OBJECT (pipeline));
3,完整的源代碼如下所示:
#include <glib.h>
//定義消息處理函數,
static gboolean bus_call(GstBus *bus,GstMessage *msg,gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;//這個是主循環的指針,在接受EOS消息時退出循環
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;
}
int main(int argc,char *argv[])
{
GMainLoop *loop;
GstElement *pipeline,*source,*decoder,*sink;//定義組件
GstBus *bus;
gst_init(&argc,&argv);
loop = g_main_loop_new(NULL,FALSE);//創建主循環,在執行 g_main_loop_run後正式開始循環
if(argc != 2)
{
g_printerr("Usage:%s <mp3 filename>\n",argv[0]);
return -1;
}
//創建管道和組件
pipeline = gst_pipeline_new("audio-player");
source = gst_element_factory_make("filesrc","file-source");
decoder = gst_element_factory_make("mad","mad-decoder");
sink = gst_element_factory_make("autoaudiosink","audio-output");
if(!pipeline||!source||!decoder||!sink){
g_printerr("One element could not be created.Exiting.\n");
return -1;
}
//設置 source的location 參數。即 文件地址.
g_object_set(G_OBJECT(source),"location",argv[1],NULL);
//得到 管道的消息總線
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
//添加消息監視器
gst_bus_add_watch(bus,bus_call,loop);
gst_object_unref(bus);
//把組件添加到管道中.管道是一個特殊的組件,可以更好的讓數據流動
gst_bin_add_many(GST_BIN(pipeline),source,decoder,sink,NULL);
//依次連接組件
gst_element_link_many(source,decoder,sink,NULL);
//開始播放
gst_element_set_state(pipeline,GST_STATE_PLAYING);
g_print("Running\n");
//開始循環
g_main_loop_run(loop);
g_print("Returned,stopping playback\n");
gst_element_set_state(pipeline,GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));
return 0;
}
4,編譯運行
./test2 /home/phinecos/test.mp3
作者:洞庭散人
出處:http://phinecos.cnblogs.com/
本博客遵從Creative Commons Attribution 3.0 License,若用於非商業目的,您可以自由轉載,但請保留原作者信息和文章鏈接URL