如何在 Qt 中实现基于 GStreamer 的视频小部件?

Posted

技术标签:

【中文标题】如何在 Qt 中实现基于 GStreamer 的视频小部件?【英文标题】:How to implement a video widget in Qt that builds upon GStreamer? 【发布时间】:2010-12-24 19:01:24 【问题描述】:

我想使用 Qt 创建一个可以播放本地视频文件的简单 GUI 应用程序。我可以使用 Phonon 来完成所有幕后工作,但我需要有更多的控制权。我已经使用 decodebin 和 autovideosink 元素成功地实现了 GStreamer 管道。现在我想使用 Qt 小部件将输出引导至。

有没有人成功做到这一点? (我想是的,因为有基于 GStreamer 的基于 Qt 的视频播放器。)有人能指出我正确的方向吗?

注意:这个问题类似于我之前发布的关于如何将 Qt 与传入的 RTP 流连接的问题。这似乎很有挑战性。我想这个问题会更容易回答。

更新 1

Patrice 关于使用 libVLC 的建议已经很有帮助了。这是在 VLC 网站上找到的代码的一个更简洁的版本: Sample for Qt + libVLC。 但是,我最初的问题仍然存在:如何将 GStreamer 连接到 Qt 小部件?

更新 2

经过一些实验,我最终得到了this working sample。这取决于我自己的小 GstSupport 库中的 GstWidget.h 和 GstWidget.cpp。但请注意,目前仅在 Mac 版本的 Qt 上进行了测试。

【问题讨论】:

嘿,Update 2 中的链接已损坏。如果可能的话,你能修复它们吗? 谢谢。顺便说一句,你能帮我solving a similar problem here吗? 【参考方案1】:

要将 Gstreamer 与您的 QWidget 连接,您需要使用 QWidget::winId() 获取窗口句柄并将其传递给 gst_x_overlay_set_xwindow_id();

粗略示例代码:

    sink = gst_element_factory_make("xvimagesink", "sink");
    gst_element_set_state(sink, GST_STATE_READY);

    QApplication::syncX();
    gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), widget->winId());

此外,您还希望您的小部件由本机窗口支持,这可以通过在应用程序级别设置 Qt::AA_NativeWindows 属性或在小部件级别设置 Qt::WA_NativeWindow 属性来实现。

【讨论】:

这实际上对我不起作用。如果我在调用 winId 之后调用 QApplication::syncX(),它会起作用。在最近的 Qt 版本中,调用 winId 会自动将您的小部件转换为原生小部件。下单见***.com/questions/3573483/…【参考方案2】:

由于 Phonon 是基于 gstreamer 的,因此查找详细信息的地方是 Phonon 源代码树(可在此处获得:http://gitorious.org/phonon/import/trees/master)。对于视频播放器,您很可能需要一个视频显示小部件,例如 gstreamer/videowidget.h (cpp),它又使用 X11 渲染器 (gstreamer/x11renderer.h, cpp)。使用的接收器是xvimagesink,如果无法创建第一个接收器,则会退回到ximagesink。

基本技巧是用视频输出覆盖 VideoWidget。执行此操作所需的 X11 句柄是使用 QWidget::winId 方法检索的,该方法是特定于平台的(与接收器一样,所以没什么大不了的)。

此外,如果覆盖不可用,则使用QWidgetVideoSink,它将视频帧转换为WidgetRenderer 类的单独帧。反过来,这个类使当前帧可用作 QImage 对象,为任何类型的处理做好准备。

所以要回答您的问题 - 使用叠加层(作为 X11Renderer)或从视频流中提取单个 QImage(作为 QWidgetVideoSink)

【讨论】:

【参考方案3】:

VLC 版本是基于 QT 的视频播放器(从 0.99 版开始)。它也允许流式传输或读取流:您可以在此处找到所需的所有信息:http://wiki.videolan.org/Developers_Corner。您只需创建播放器的一个实例并将其关联到一个小部件。然后你就可以完全控制播放器了。

我已经测试过它(在 Linux 和 Windows 上)播放本地音乐和视频文件,它工作正常。

自己试试看吧。

希望对您有所帮助。

编辑: 似乎如果你想使用 VLC,你需要编写或找到(我不知道是否存在)一个 GStreamer 编解码器,如 videolan wiki 上的解释。我想我会这样做。

【讨论】:

我是 VLC 播放器的忠实粉丝,但我不知道你可以将它连接到 Qt 小部件。您是在谈论 libVLC,还是使用 DBus 与 VLC 通信? 我说的是 libVLC。你在这里有一个例子:wiki.videolan.org/LibVLC_SampleCode_Qt

以上是关于如何在 Qt 中实现基于 GStreamer 的视频小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 和 Qt Quick QML 应用程序中实现简化的双向数据绑定

如何在自定义文件浏览对话框Qt C++中实现返回和下一步按钮

如何在Python和Qt Quick QML应用程序中实现简化的双向数据绑定

如何在qt中实现代码完成[关闭]

如何在 QT 中实现自定义模型的 removeRow() 函数?

如何在 Qt 无框窗口中显示 GStreamer 视频?