将 Gstreamer 与 Qt 连接以便在 Qt Widget 中播放 gstreamer 视频
我尝试使用 phonon 播放视频,但未能成功。 Off-late通过Qt论坛了解到,即使是最新版本的Qt也不支持phonon。就在那时我开始使用 Gstreamer。关于如何将 Gstreamer 窗口与 Qt 小部件连接有什么建议吗?我的目标是在 Qt 小部件上使用 Gstreamer 播放视频。那么如何链接 Gstreamer 窗口和 Qt 小部件呢?
我通过winid()
成功获取了小部件的Id
。 此外,在 Gregory Pakosz 的帮助下,我在我的应用程序中添加了以下两行代码 -
QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), widget->winId());
但是我无法将 Qt 小部件与 gstreamer 视频窗口链接。
这就是我的示例代码看起来像:-
int main(int argc, char *argv[])
{
printf("winid=%d\n", w.winId());
gst_init (NULL,NULL);
/* create a new bin to hold the elements */
bin = gst_pipeline_new ("pipeline");
/* create a disk reader */
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc);
g_object_set (G_OBJECT (filesrc), "location", "PATH_TO_THE_EXECUTABLE", NULL);
demux = gst_element_factory_make ("mpegtsdemux", "demuxer");
if (!demux) {
g_print ("could not find plugin \"mpegtsmux\"");
return -1;
}
vdecoder = gst_element_factory_make ("mpeg2dec", "decode");
if (!vdecoder) {
g_print ("could not find plugin \"mpeg2dec\"");
return -1;
}
videosink = gst_element_factory_make ("xvimagesink", "play_video");
g_assert (videosink);
/* add objects to the main pipeline */
gst_bin_add_many (GST_BIN (bin), filesrc, demux, vdecoder, videosink, NULL);
/* link the elements */
gst_element_link_many (filesrc, demux, vdecoder, videosink, NULL);
gst_element_set_state(videosink, GST_STATE_READY);
QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());
/* start playing */
gst_element_set_state (bin, GST_STATE_PLAYING);
}
您能否更详细地解释一下 gst_x_overlay_set_xwindow_id() 在我的上下文中的用法?
我可以获得有关如何在 Qt 下集成 gstreamer 的任何提示吗? 请帮我解决这个问题。
I tried using phonon to play the video but could not succeed. Off-late came to know through the Qt forums that even the latest version of Qt does not support phonon. That's when I started using Gstreamer. Any suggestions as to how to connect the Gstreamer window with the Qt widget? My aim is to play a video using Gstreamer on the Qt widget. So how do I link the Gstreamer window and the Qt widget?
I am successful in getting the Id
of the widget through winid()
.
Further with the help of Gregory Pakosz, I have added the below 2 lines of code in my application -
QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), widget->winId());
However am not able to link the Qt widget with the gstreamer video window.
This is what my sample code would look like :-
int main(int argc, char *argv[])
{
printf("winid=%d\n", w.winId());
gst_init (NULL,NULL);
/* create a new bin to hold the elements */
bin = gst_pipeline_new ("pipeline");
/* create a disk reader */
filesrc = gst_element_factory_make ("filesrc", "disk_source");
g_assert (filesrc);
g_object_set (G_OBJECT (filesrc), "location", "PATH_TO_THE_EXECUTABLE", NULL);
demux = gst_element_factory_make ("mpegtsdemux", "demuxer");
if (!demux) {
g_print ("could not find plugin \"mpegtsmux\"");
return -1;
}
vdecoder = gst_element_factory_make ("mpeg2dec", "decode");
if (!vdecoder) {
g_print ("could not find plugin \"mpeg2dec\"");
return -1;
}
videosink = gst_element_factory_make ("xvimagesink", "play_video");
g_assert (videosink);
/* add objects to the main pipeline */
gst_bin_add_many (GST_BIN (bin), filesrc, demux, vdecoder, videosink, NULL);
/* link the elements */
gst_element_link_many (filesrc, demux, vdecoder, videosink, NULL);
gst_element_set_state(videosink, GST_STATE_READY);
QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());
/* start playing */
gst_element_set_state (bin, GST_STATE_PLAYING);
}
Could you explain more in detail about the usage of gst_x_overlay_set_xwindow_id() wrt my context?
Could I get any hint as to how I can integrate gstreamer under Qt?
Please help me solve this problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我刚刚使用 python 做了同样的事情。我要做的就是连接到总线上的“sync-message::element”,并侦听在视频接收器已设置。它向您发送该消息内的接收器,这就是您向其传递窗口 ID 的地方。
I just did this same thing using python. What I had to do was connect to 'sync-message::element' on the bus and listen for a message called 'prepare-xwindow-id' (disregard the name as it works on all platforms, not just X11) sent after the video sink is setup. It sends you the sink inside that message, and that is where you pass it the window id.
如果元素链接正确,上面给出的示例代码会将 GStreamer 视频窗口链接到 QtWidget。
The sample code given above will link GStreamer video window to QtWidget provided the elements are linked correctly.
http://cgit.freedesktop.org/gstreamer/ gst-plugins-base/tree/tests/examples/overlay
有一个最小的 Qt 示例。
在您的代码中,您应该在将状态更改为就绪之前设置窗口 ID(尽管我不能 100% 确定这是问题所在)。
对于播放,您最好使用 playbin2 元素,如下所示(完全未经测试):
.. 检查管道/playbin 总线上的错误/状态更改/标签/eos 等消息
http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/overlay
has a minimal Qt example.
In your code, you should probably set the window ID before you do the state change to ready (I'm not 100% sure this is the problem though).
For playback, you should idally use the playbin2 element, something like this (completely untested):
.. check for messages like error/statechanges/tags/eos on pipeline/playbin bus
将 gstreamer 包装到可用的 C++/Qt 类中的项目,包括示例代码:
http://code.google.com/p/qbtgstreamer/
我不知道关于直接方法,因为我对 gstreamer 本身不熟悉。
A project wrapping gstreamer into usable C++/Qt classes including example code:
http://code.google.com/p/qbtgstreamer/
I don't know about a direct approach, as I am not familiar with gstreamer itself.