源码
#include <gst/gst.h>
int
main (int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Build the pipeline */
pipeline =
gst_parse_launch
("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
NULL);
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg =
gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Free resources */
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
代码走读
首先include了<gst/gst.h>,该头文件包含了GStreamer的对外api
/* Initialize GStreamer */
gst_init (&argc, &argv);
首先调用的是gst_init(),它的作用是:
- 初始化所有内部结构
- 检查哪些插件是能够获取的
- 执行传递给GStreamer的命令行选项
/* Build the pipeline */
pipeline =
gst_parse_launch
("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
NULL);
这一行是这个sample的核心,主要有两个关键:gst_parse_launch和playbin
gst_parse_launch
GStreamer是一个设计用来处理多媒体流的框架。媒体从“source” “element”(生产者)到“sink” :“element”(消费者),经过一系列执行各种任务的中间elements。所有相互连接的elements的集合称为“pipeline”。
在GStreamer中,您通常通过手动组装各个element来构建pipeline,但是,当pipeline足够简单并且您不需要任何高级特性时,您可以采用快捷方式:gst_parse_launch()。
这个函数接受pipeline的文本表示,并将其转换为实际的pipeline,这非常方便
playbin
那么,我们要求gst_parse_launch()为我们构建什么样的pipeline呢?这里进入第二个关键点:我们正在构建一个由称为playbin的单个element组成的pipeline。
playbin是一个特殊的元素,它既是source又是sink,是一个完整的pipeline。在内部,它创建并连接播放媒体所需的所有必要element,因此您不必担心它。
它不允许手动pipeline的控制粒度,但是,它仍然允许足够的自定义,以满足广泛的应用程序。包括本教程。
在本例中,我们只向playbin传递了一个参数,即我们想要播放的媒体的URI。试着把它改成别的东西!无论是http://还是file:// URI, playbin都将透明地实例化适当的GStreamer源!
如果您输入了错误的URI,或者文件不存在,或者您缺少了一个插件,GStreamer提供了几种通知机制,但是我们在这个例子中所做的唯一的事情就是在错误时退出,所以不要期望得到太多的反馈。
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
这一行突出了另一个有趣的概念:状态。每个GStreamer元素都有一个相关联的状态,您可以或多或少地将其视为普通DVD播放器中的播放/暂停按钮。现在,只要说明播放不会开始,除非您将管道设置为PLAYING状态。
在这一行中,gst_element_set_state()将管道(记住,我们唯一的元素)设置为PLAYING状态,从而启动播放。
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg =
gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
这几行将阻塞,直到出现错误或找到流的结尾。gst_element_get_bus()检索管道的总线,gst_bus_timed_pop_filtered()将阻塞,直到您通过该总线接收到ERROR或EOS (end - stream)。
就是这样!从这一点开始,GStreamer负责一切。当媒体到达终点(EOS)或遇到错误(尝试关闭视频窗口或拔掉网线)时,执行将结束。应用程序总是可以通过在控制台中按control-C来停止。
/* Free resources */
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
在终止应用程序之前,我们需要做几件事情,以便在结束后正确地进行整理。
在本例中,gst_bus_timed_pop_filtered()返回了一条需要用gst_message_unref()释放的消息
Gst_element_get_bus()为必须使用gst_object_unref()释放的总线添加了一个引用。将管道设置为NULL状态将确保它释放已分配的任何资源最后,取消对管道的引用将破坏管道及其所有内容。
总结
我们学会了:
- 使用gst_init初始化GStreamer
- 通过gst_parse_launch()以文本描述的方式快速构建一个pipeline
- 使用playbin创建一个自动播放的pipeline
- 使用gst_element_set_state()通知GStreamer开始播放
- 让GStreamer负责一切,使用gst_element_get_bus()和gst_bus_timed_pop_filtered()