如何在 C 中使用 gstreamer 播放音频?

How to play audio with gstreamer in C?

我正在尝试使用 C 中的 Gstreamer 播放音频。 我正在使用笔记本电脑,Ubuntu 16.

为了玩游戏,我使用了这个管道,它正在运行:

gst-launch-1.0 filesrc location=lambo-engine.mp3 ! decodebin ! audioconvert ! autoaudiosink

但是当我把它转换成 C:

GstElement *pipeline, *source, *decode, *audioconvert, *sink;
GMainLoop *loop;
GstBus *bus;
GstMessage *msg;

int main(int argc, char *argv[]) {
    /* Initialize GStreamer */
    gst_init (&argc, &argv);

    /* Create the elements */
    source          = gst_element_factory_make("filesrc",  NULL);
    decode          = gst_element_factory_make("decodebin",     NULL);
    audioconvert    = gst_element_factory_make("audioconvert",  NULL);
    sink            = gst_element_factory_make("autoaudiosink", NULL);
    // Set parameters for some elements
    g_object_set(G_OBJECT(source),  "location", "lambo-engine.mp3", NULL);
    /* Create the empty pipeline */
    pipeline = gst_pipeline_new ("pipeline");

    /* Build the pipeline */
    gst_bin_add_many (GST_BIN (pipeline), source, decode, audioconvert, sink, NULL);

      if (gst_element_link_many(source, decode, audioconvert, sink, NULL) != TRUE){
        g_error("Failed to link save elements!");
        gst_object_unref (pipeline);
        return -1;
    }
  
    /* Start playing */
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    bus = gst_element_get_bus (pipeline);
    gst_object_unref (bus);

    /* now run */
    g_main_loop_run (loop);

    /* Free pipeline */
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (GST_OBJECT(pipeline));
    return 0;
}

我可以成功构建它。但是当我运行它的时候,它return错误can't link elements:

** (example:2516): ERROR **: 22:59:42.310: Failed to link save elements! Trace/breakpoint trap (core dumped)

请大家帮我找出错误。

非常感谢

Gstreamer 以作为元素列表的管道为中心。元素有垫来交换数据。在您的示例中,decodebin 有一个输出垫,而 audioconvert 有一个输入垫。在流水线的开始,需要 linked.

这是双方就数据格式以及其他一些信息达成一致的时候,例如谁负责计时,也许还有更多格式细节。

你的问题是因为 decodebin 实际上不是一个真正的元素。在 运行 时,当 filesrc 启动时,它告诉 decodebin 它有什么 pad,decodebin 在内部创建元素来处理该文件。

例如: filesrc location=test.mp4 ! decodebin 将按以下顺序 运行:

  • 延迟 link 因为类型未知
  • 启动文件
  • filesrc 说“正在尝试 link,我有一个格式为 MP4(h264)
  • 的便笺簿
  • decodebin 看到这个请求,然后动态创建一个可以处理 mp4 文件的 h264 解析元素
  • decodebin 现在有足够的信息来描述它的 pad,它 link 是管道的其余部分
  • 视频开始播放

因为您使用 c 来执行此操作,所以您 link 在 filesrc 加载文件之前的管道。这意味着 decodebin 在启动时不知道它的格式,因此无法 link.

要解决此问题,您有两种选择:

1.) 将 decodebin 换成只支持一种类型的东西。例如,如果您知道您的视频将始终是带有 h264 的 mp4,您可以使用 h264parse 而不是 decodebin。因为 h264parse 只适用于一种格式,它一开始就知道它是填充格式,并且能够 link 没有问题。

2.) 重新实现智能延迟 linking。您可以阅读文档以获取更多信息,但您可以延迟 linking 管道,并在有足够信息时安装回调以完成 linking。这就是 gst-launch-1.0 在幕后所做的。这样做的好处是更加灵活:decodebin 支持的任何东西都可以工作。缺点是它要复杂得多,涉及到您的大量工作,而且更脆弱。如果你能摆脱它,请尝试修复 1