前言
本文是GStreamer学习笔记,也可以看成是对原文的意译。
这些教程描述了理解其余教程所需的GStreamer主题。
GStreamer教程:
环境
系统环境
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic
Linux version : 5.3.0-46-generic ( buildd@lcy01-amd64-013 )
Gcc version: 7.5.0 ( Ubuntu 7.5.0-3ubuntu1~18.04 )
软件信息
version :
GStreamer-1.0
正文
1. 目标
惯例性的 “Hello world” 程序,正常的是在屏幕上打印”Hello world”,但是现在是处理多媒体框架,所以将是播放视频。
下面代码是播放视频的GStreamer应用程序代码
2. 代码
basic-tutorial-1.c
#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);
/* See next tutorial for proper error message handling/parsing */
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
"variable set for more details.");
}
/* Free resources */
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
编译
gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`
./basic-tutorial-1
本教程将打开一个窗口并显示一部电影,并附带音频。媒体是从 Internet 获取的,因此窗口可能需要几秒钟才能出现,具体取决于您的连接速度。此外,没有延迟管理(缓冲),因此在连接速度较慢的情况下,电影可能会在几秒钟后停止。了解基础教程 12: 流媒体如何解决此问题。
3. 演练
让我们回顾一下这些代码行,看看它们做了什么:
/* Initialize GStreamer */
gst_init (&argc, &argv);
这必须始终是您的第一个 GStreamer 命令。除其他外, gst_init ():
- 初始化所有内部结构
- 检查哪些插件可用
- 执行任何用于 GStreamer 的命令行选项
如果您始终将命令行参数传递给gst_initargc
() ,您的应用程序将自动受益于 GStreamer 标准命令行选项(更多信息请参见基础教程 10: GStreamer工具)argv
pipeline =
gst_parse_launch
("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
NULL);
这一行是本教程的核心,并举例说明了两个关键点:gst_parse_launch () 和playbin。
3.1 gst_parse_launch
GStreamer 是一个设计用于处理多媒体流的框架。媒体从“源”元素(生产者)传播到“汇”元素(消费者),经过一系列执行各种任务的中间元素。所有互连元素的集合称为“管道”。
在 GStreamer 中,您通常通过手动组装各个元素来构建管道,但是,当管道足够简单并且您不需要任何高级功能时,您可以参考此链接: gst_parse_launch ()。
此函数采用管道的文本表示并将其转换为实际管道,这非常方便。事实上,这个函数非常方便,有一个完全围绕它构建的工具,您会非常熟悉(参见基础教程 10: GStreamer工具以了解 gst-launch-1.0和 gst-launch-1.0语法)。
3.2 playbin
这里进入第二个关键点:我们正在构建一个由一个名为playbin的元素组成的管道。
playbin是一个特殊的元素,它充当源和接收器,是一个完整的管道。在内部,它创建并连接播放媒体所需的所有元素,因此您不必担心。
它不允许手动管道所具有的控制粒度,但是,它仍然允许足够的定制来满足广泛的应用程序。包括本教程。
在这个例子中,我们只向playbin传递了一个参数,即我们要播放的媒体的 URI。尝试将其更改为其他内容!无论是URIhttp://
还是file://
URI,playbin都会透明地实例化相应的 GStreamer 源!
如果您输入错误的 URI,或者文件不存在,或者您缺少插件,GStreamer 提供了几种通知机制,但我们在此示例中所做的唯一事情是错误退出,因此不要期望太多反馈。
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
上面一行代码突出了另一个有趣的概念:状态。每个 GStreamer 元素都有一个关联的状态,可以将其视为普通 DVD 播放器中的播放/暂停按钮。现在,足以说明播放不会开始,除非将管道设置为 PLAYING 状态。
在这一行中,gst_element_set_state () 将pipeline
(我们唯一的元素,记住)设置为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);
/* See next tutorial for proper error message handling/parsing */
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
"variable set for more details.");
}
这些行将一直等到发生错误或找到流的结尾。gst_element_get_bus () 检索管道的总线,并且 gst_bus_timed_pop_filtered () 将阻塞,直到您通过该总线收到 ERROR 或EOS
(End-Of-Stream)。这条线不用太担心,GStreamer 总线在基础教程 2: GStreamer 概念中进行了解释。
就是这样!从此时起,GStreamer 负责一切。当媒体到达终点 (EOS) 或遇到错误(尝试关闭视频窗口,或拔下网线)时,执行将结束。始终可以通过在控制台中按 control-C 来停止应用程序。
3.3 清理
但是,在终止应用程序之前,我们需要做一些事情来正确地整理好我们自己。
/* Free resources */
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 () 释放的消息(有关消息的更多信息, 请参见基础教程 2: GStreamer 概念)。
gst_element_get_bus () 添加了对必须使用gst_object_unref () 释放的总线的引用。将管道设置为 NULL 状态将确保它释放已分配的任何资源(有关状态的更多信息,请参见 基础教程 3: 动态管道)。最后,取消引用管道将破坏它,以及它的所有内容。
4. 结论
第一个GStreamer教程结束,回顾下学到的东西:
- 如何使用gst_init()初始化GStreamer
- 如何使用gst_parse_launch()从文本描述重快速构建管道
- 如何使用playbin()创建自动播放管道
- 如何使用gst_element.set_state()向GStreamer发出信号开始播放
- 如何使用gst_element.get_bus()和gst_bus_timed_pop_filtered()让GStremer处理一切
下一篇基础教程 2: GStreamer 概念将继续介绍更多基本的GStreamer元素,并向您展示如何手动构建管道。