繁体   English   中英

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

[英]How to play audio with gstreamer in C?

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

为了玩,我使用这个管道并且它正在工作:

gst-launch-1.0 filesrc location=lambo-engine.mp3 ! 解码箱! 音频转换! 自动收音机

但是当我将它转换为 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;
}

我可以成功建立它。 但是当我运行它时,它返回错误无法链接元素:

**(示例:2516):错误 **:22:59:42.310:无法链接保存元素! 跟踪/断点陷阱(核心转储)

请有人帮我找出错误。

太感谢了

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

这是 pad 就数据格式以及其他一些信息达成一致的时候,例如谁负责计时以及可能更多的格式细节。

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM