我尝试使用声子播放视频,但无法成功。通过Qt论坛了解到,甚至最新版本的Qt也不支持声子。多数民众赞成在我开始使用Gstreamer时。有关如何将Gstreamer窗口与Qt小部件连接的建议吗?我的目标是在Qt小部件上使用Gstreamer播放视频。那么我如何链接gstreamer窗口和Qt小部件呢? /强>
我成功通过winid()获取小部件的ID。 在Gregory Pakosz的帮助下,我在我的应用程序中添加了以下2行代码 -
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的提示? 请帮我解决这个问题
答案 0 :(得分:2)
http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/overlay
有一个最小的Qt例子。
在您的代码中,您应该在状态更改准备好之前设置窗口ID(我不是100%确定这是问题)。
对于播放,您应该暂时使用playbin2元素,如下所示(完全未经测试):
GstElement *playbin, *videosink;
gchar *uri;
playbin = gst_element_factory_make ("playbin2", "myplaybin");
videosink = gst_element_factory_make ("xvimagesink", NULL);
g_object_set (playbin, "video-sink", videosink, NULL);
uri = g_filename_to_uri ("/path/to/file", NULL, NULL);
g_object_set (playbin, "uri", uri, NULL);
g_free (uri);
/* NOTE: at this point your main window needs to be realized,
* ie visible on the screen, and you might need to make sure
* that your widget w indeed has a 'native window' (just some
* things to check for if it doesn't work; there should be Qt
* API for this kind of thing if needed) */
QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());
gst_element_set_state (playbin, GST_STATE_PLAYING);
..检查管道/ playbin总线上的错误/ statechanges / tags / eos等消息
答案 1 :(得分:1)
我只是使用python做了同样的事情。我必须要做的是连接到总线上的'sync-message :: element'并听取一条名为'prepare-xwindow-id'的消息(忽略名称,因为它适用于所有平台,而不仅仅是X11)视频接收器已设置。它会向您发送该消息中的接收器,这就是您向其传递窗口ID的位置。
答案 2 :(得分:1)
上面给出的示例代码会将GStreamer视频窗口链接到QtWidget,前提是元素链接正确。
// link filesrc to demuxer
gst_element_link(filesrc,demux)
// link vdecoder to filesink
gst_element_link_many(vdecoder,filesink,NULL)
/*
The demuxer will be linked to the decoder dynamically.
The source pad(s) will be created at run time,
by the demuxer when it detects the amount and nature of streams.
Connect a callback function which will be executed
when the "pad-added" is emitted.
*/
g_signal_connect(demux,"pad-added",G_CALLBACK(on_pad_added),vdecoder);
// callback definition
static void on_pad_added(GstElement* element,GstPad* pad,gpointer* data)
{
GstPad* sinkpad;
GstElement * decoder = (GstElement*)data;
GstCaps* caps;
GstStructure* str;
gchar* tex;
caps = gst_pad_get_caps(pad);
str = gst_caps_get_structure(caps,0);
tex = (gchar*)gst_structure_get_name(str);
if(g_strrstr(tex,"video"))
{
sinkpad = gst_element_get_static_pad(decoder,"sink");
gst_pad_link(pad,sinkpad);
gst_object_unref(sinkpad);
}
}
答案 3 :(得分:0)
将gstreamer包装成可用的C ++ / Qt类的项目,包括示例代码: http://code.google.com/p/qbtgstreamer/
我不知道直接的方法,因为我不熟悉gstreamer本身。