GStreamer Basic Tutorial 1 Hello World

"GStreamer 基本教程:1 Hello World"

Posted by Stephen on March 13, 2022

前言

本文是GStreamer学习笔记,也可以看成是对原文的意译。

这些教程描述了理解其余教程所需的GStreamer主题。

GStreamer教程:

基础教程 : GStreamer 介绍

基础教程 1: Hello world!

基础教程 2: GStreamer 概念

基础教程 3: 动态管道

基础教程 4: 时间管理

基础教程 5: GUI工具包集成

基础教程 6: 媒体格式和pad功能

基础教程 7: 多线程和Pad可用性

基础教程 8: 管道短路操作

基础教程 9: 媒体信息收集

基础教程 10: GStreamer工具

基础教程 11: 调试工具

基础教程 12: 流媒体

基础教程 13: 播放速度

基础教程 14: 有用的元素

基础教程 16: 特定平台元素

环境

系统环境

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.0gst-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元素,并向您展示如何手动构建管道。

后记