跳转至

Hello world!

目标

要获得对软件库的第一印象,没有什么比在屏幕上打印 “Hello World” 更好的了!

但是由于我们正在处理多媒体框架,因此我们将播放视频。

不要被下面的代码量吓到:只有 4 行代码可以做真正的工作。其余的是清理代码,在 C 语言中,这总是有点冗长。

事不宜迟,为您的第一个 GStreamer 应用程序做好准备......

Hello world

将此代码复制到名为 basic-tutorial-1.c 的文本文件中(或在 GStreamer 安装中找到它)。

#include <gst/gst.h>

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif

int
tutorial_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://gstreamer.freedesktop.org/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_printerr ("An error occurred! Re-run with the GST_DEBUG=*:WARN "
        "environment variable set for more details.\n");
  }

  /* Free resources */
  gst_message_unref(msg);
  gst_object_unref(bus);
  gst_element_set_state(pipeline, GST_STATE_NULL);
  gst_object_unref(pipeline);
  return 0;
}

int
main (int argc, char *argv[])
{
#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
  return gst_macos_main ((GstMainFunc) tutorial_main, argc, argv, NULL);
#else
  return tutorial_main (argc, argv);
#endif
}

按照在 Linux 上安装在 Mac OS X 上安装在 Windows 上安装中的说明进行编译。如果您遇到编译错误,请仔细检查这些部分中给出的说明。

如果一切正常,请启动可执行文件!您应该会看到一个弹出窗口,其中包含直接从 Internet 播放的视频以及音频。 祝贺!

需要帮助?

如果您需要编译此代码的帮助,请参阅针对您的平台构建教程部分:Linux、Mac OS X 或 Windows 上,或在 Linux 上使用以下特定命令:

gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`

如果您需要运行此代码的帮助,请参阅适用于您的平台的运行教程部分:Linux、Mac OS X 或 Windows 的

必需安装的库:gstreamer-1.0

本教程将打开一个窗口显示电影,并附带音频。媒体是从 Internet 获取的,因此该窗口可能需要几秒钟才能显示,具体取决于您的连接速度。此外,没有延迟管理(缓冲),因此在连接速度较慢的情况下,电影可能会在几秒钟后停止。了解基本教程 12:流式处理如何解决此问题。

代码走查

让我们回顾一下这些代码行,看看它们有什么作用:

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

这必须始终是您的第一个 GStreamer 命令。除其他外, gst_init(): - 初始化所有内部结构 - 检查哪些插件可用 - 执行任何用于 GStreamer 的命令行选项

如果您始终传递命令行参数 argc 和 argv 到 gst_init() 您的应用程序将自动受益于 GStreamer 标准命令行选项(更多内容请参阅基本教程 10:GStreamer 工具)

 /* Build the pipeline */
  pipeline =
      gst_parse_launch
      ("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm",
      NULL);

这行是本教程的核心,并举例说明了两个关键点:gst_parse_launch() 和 playbin。

gst_parse_launch

GStreamer 是一个旨在处理多媒体流的框架。媒体从“源”元素(生产者)向下传播到“接收器”元素(消费者),通过一系列执行各种任务的中间元素。所有互连元素的集合称为“管道”。

在 GStreamer 中,您通常通过手动组装 单个元素,但是,当管道足够简单时,您确实 不需要任何高级功能,您可以采用快捷方式: gst_parse_launch() 中。

此函数采用管道的文本表示并将其转换为实际的管道,这非常方便。事实上,此函数非常方便,有一个完全围绕它构建的工具,您将非常熟悉它(请参阅基本教程 10:GStreamer 工具以了解 gst-launch-1.0 和 gst-launch-1.0 语法)。

playbin

那么,我们要求 gst_parse_launch() 为我们构建什么样的管道呢?这里进入了第二个关键点:我们正在构建一个由名为 playbin 的单个元素组成的管道。

Playbin 是一个特殊的元素,它既是源又是 sink,是一个完整的管道。在内部,它创建并连接播放媒体所需的所有元素,因此您不必担心。

它不允许手动管道那样的控制粒度,但是,它仍然允许足够的自定义以满足广泛的应用程序。包括本教程。

在这个例子中,我们只向 playbin 传递了一个参数,即我们想要播放的媒体的 URI。试着把它改成别的呢!无论是 http:// 还是 file://,playbin 都会透明地实例化相应的 GStreamer 源!

如果键入了错误的 URI,或者文件不存在,或者缺少插件,GStreamer 提供了多种通知机制,但在此示例中,我们唯一要做的就是出错时退出,因此不要期望有太多反馈。

  /* Start playing */
  gst_element_set_state(pipeline, GST_STATE_PLAYING);

这行突出显示了另一个有趣的概念:状态。每个 GStreamer 元素都有一个关联的状态,您或多或少可以将其视为常规 DVD 播放器中的 Play/Pause 按钮。现在,可以说,除非您将管道设置为 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);

这些行将等待,直到发生错误或找到流的末尾。gst_element_get_bus() 检索管道的总线,并且 gst_bus_timed_pop_filtered() 将阻塞,直到您通过该总线收到 ERROR 或 EOS (End-Of-Stream)。不要太担心这条线路,GStreamer 总线在基本教程 2:GStreamer 概念中进行了解释。

就是这样!从这时起,GStreamer 会处理所有事情。当媒体到达其末尾 (EOS) 或遇到错误(尝试关闭视频窗口或拔下网线)时,执行将结束。始终可以通过在控制台中按 control-C 来停止应用程序。

清理

但是,在终止应用程序之前,我们需要做一些事情来正确整理自己。

  /* Free resources */
  gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;

请始终阅读您使用的函数的文档,以了解是否应该在使用它们后释放它们返回的对象。

在这种情况下,gst_bus_timed_pop_filtered() 返回了一条消息,该消息需要使用 gst_message_unref() 释放(有关消息的更多信息,请参阅 基本教程 2:GStreamer 概念)。

gst_element_get_bus() 添加了对必须使用 gst_object_unref() 释放的总线的引用。将管道设置为 NULL 状态将 确保它释放已分配的所有资源(有关状态的更多信息,请参阅 基本教程 3:动态管道)。最后,取消引用管道将销毁它及其所有内容。

总结

您的第一个教程 GStreamer 就这样结束了。我们希望它的简洁可以作为这个框架有多么强大的示例!

让我们回顾一下。今天我们了解到: - 如何使用 gst_init() 初始化 GStreamer。 - 如何使用 gst_parse_launch() 从文本描述快速构建管道。 - 如何使用 playbin 创建自动播放管道。 - 如何使用 gst_element_set_state() 通知 GStreamer 开始回放。 - 如何坐下来放松,而 GStreamer 使用 gst_element_get_bus() 和 gst_bus_timed_pop_filtered() 处理一切。

下一个教程将继续介绍更多基本的 GStreamer 元素,并向您展示如何手动构建管道。

很高兴您来到这里,很快再见!

评论