在播放视频的 QWidget 之上包含 QML 的 QDeclarativeView 的透明度(使用 phonon 或 libvlc)
我目前正在开发一个视频播放器。
最顶层的GUI是用QML编写的。它应该对下层是透明的。它包含控制元素,一些列表等,它使用QDeclarativeView
显示。
描述
QDeclarativeView *upperLayer = new QDeclarativeView(this);
upperLayer->setSource(QUrl("/home/projects/QtVideo/qml/videoControl.qml"));
upperLayer->setStyleSheet(QString("background: transparent");
upperLayer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
uperLayer->showFullScreen();
下面一层是一个QWidget:我使用libvlc来显示视频内容 在此小部件中。
原因:我收到的是 MPEG-TS,据我所知,它无法通过声子解码。因此,我需要 libvlc 来解码传入的 *.ts
流并将输出显示到显示器上。
QWidget *lowerLayer = new QWidget(this);
lowerLayer.setGeometry(QString("background: red"));
QUrl* url = new QUrl("file:///home/projects/QtVideo/video.ts");
libvlc_instance_t*vlcObject;
libvlc_media_t*vlcMedia;
libvlc_media_player_t*vlcPlayer;
vlcPlayer = NULL;
if(vlcObject = libvlc_new(argc, argv)) == NULL)
{
printf("Not able to initialize";
exit(1);
}
if(vlcPlayer && libvlc_media_player_is_playing(vlcPlayer))
{
libvlc_media_player_stop(vlcPlayer);
}
vlcPlayer = libvlc_media_player_new(vlcObject);
vlcMedia = libvlc_media_new_location(vlcObject, url.toString().toUtf8().constData());
libvlc_media_player_set_media(vlcPlayer, vlcMedia);
#if defined(Q_OS_MAC)
libvlc_media_player_set_nsobject(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_UNIX)
libvlc_media_player_set_x_window(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_WIN)
libvlc_media_player_set_hwnd(vlcPlayer, lowerLayer->winId());
#endif
libvlc_media_player_play(vlc_player);
两个元素,QDeclarativeView
和 QWidget
嵌入在QMainWindow
中,lowerLayer在upperLayer
之前创建, upperLayer
对lowerLayer
透明。
问题:
只要 lowerLayer 显示静态元素(例如图片或某些彩色形状),一切都可以正常工作,完全透明且功能齐全。
一旦我开始显示视频,例如使用 libvlc 描述的 *.ts
或使用 Phonon::VideoPlayer
的一些随机视频,的部分
以 lowerLayer
视频部分上方的 >upperLayerlowerLayer(默认:灰色)
的颜色显示,lowerLayer 的部分位于
或其他不包含视频元素的部分会以正确的行为显示。lowerLayer
部分上方的 upperLayer
问题:
即使正在播放视频,是否有可能以及是否、如何使上层透明?
I am currently developing a video player.
The GUI as the topmost layer is written in QML. It should be transparent to lower layers. It contains control elements, some Lists etc., It's displayed using a QDeclarativeView
.
Description
QDeclarativeView *upperLayer = new QDeclarativeView(this);
upperLayer->setSource(QUrl("/home/projects/QtVideo/qml/videoControl.qml"));
upperLayer->setStyleSheet(QString("background: transparent");
upperLayer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
uperLayer->showFullScreen();
The layer underneath is a QWidget: I use the libvlc to display the video content
in this widget.
Reason: I am receiving MPEG-TS, which can not be decoded by phonon, afaik. Therefore I need the libvlc to decode the incoming *.ts
stream and put the output onto the display.
QWidget *lowerLayer = new QWidget(this);
lowerLayer.setGeometry(QString("background: red"));
QUrl* url = new QUrl("file:///home/projects/QtVideo/video.ts");
libvlc_instance_t*vlcObject;
libvlc_media_t*vlcMedia;
libvlc_media_player_t*vlcPlayer;
vlcPlayer = NULL;
if(vlcObject = libvlc_new(argc, argv)) == NULL)
{
printf("Not able to initialize";
exit(1);
}
if(vlcPlayer && libvlc_media_player_is_playing(vlcPlayer))
{
libvlc_media_player_stop(vlcPlayer);
}
vlcPlayer = libvlc_media_player_new(vlcObject);
vlcMedia = libvlc_media_new_location(vlcObject, url.toString().toUtf8().constData());
libvlc_media_player_set_media(vlcPlayer, vlcMedia);
#if defined(Q_OS_MAC)
libvlc_media_player_set_nsobject(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_UNIX)
libvlc_media_player_set_x_window(vlcPlayer, lowerLayer->winId());
#elif defined(Q_OS_WIN)
libvlc_media_player_set_hwnd(vlcPlayer, lowerLayer->winId());
#endif
libvlc_media_player_play(vlc_player);
Both Elements, the QDeclarativeView
and the QWidget
are embedded in a QMainWindow
, lowerLayer created before the upperLayer
,upperLayer
Transparent to the lowerLayer
.
The Problem:
As long as the lowerLayer is displaying static elements such as a picture, or some colored shapes, everything works fine, full transparency and functionality.
As soon as I start displaying a video, such as the described *.ts
using the libvlc OR some random video using the Phonon::VideoPlayer
, the parts of the upperLayer
which are above the video parts of the lowerLayer
are displayed in the color of the lowerLayer(default: gray)
, the parts of the upperLayer
which are positioned above parts of the lowerLayer
or others which do not contain video elements are displayed in correct behaviour.
Question:
Is there any posibility and if, how, to get the upperLayer transparent, even if there is a video playing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您还在为这个问题而奋斗吗?遗憾的是,我没有给你一个满意的答案。我能做的就是向您指出它不起作用的原因:
http://lists.trolltech.com/qt-interest/2007-02/thread01061-0.html
请参阅上面链接中的消息 #4。
我尝试了许多不同的方法来使用 Qt 在视频(特别是 Phonon::VideoPlayer)上进行透明绘画。到目前为止,我发现的唯一方法是将覆盖的 QWidget 设置为工具提示,执行类似的操作
取决于您想要执行的操作,这可能就足够了,但(在我看来)这充其量只是一种黑客攻击。我正在积极解决这个问题,如果我能找到某种解决方案,我一定会将其发布在这里。
祝你好运。
Are you still fighting with this issue? I, sadly, do not have a satisfying answer for you. The best I can do is point you to reasons why it doesn't work:
http://lists.trolltech.com/qt-interest/2007-02/thread01061-0.html
See Message #4 in the link above.
I have tried many different methods to get transparent painting over a video (specifically Phonon::VideoPlayer) using Qt. The only method I've found so far, is to set the overlaying QWidget as a toolTip doing something like
Depending on what exactly you're wanting to do this may be sufficient, but (in my opinion) it's a hack at best. I'm actively struggling with this issue and if I can find some sort of solution, I'll be sure to post it here.
Best of luck.
您正在使用直接渲染(通过传递小部件的宽度),该渲染在该几何图形上绘制视频:
您需要使用离屏渲染并将其绘制到您的qwidget。这可以通过 opengl 上下文(复杂)或使用 libvlc 中可用的回调方法来完成。
如果您使用显示回调(libvlc_video_display_cb),如果需要,libvlc 还将生成锁定/解锁方法。在此方法中,libvlc 将期望设置一些参数,例如画布几何形状和像素格式。
也就是说,phonon 有一个 libvlc 后端,这可能会有所帮助,但根据某些因素可能仍然使用直接渲染。
you're using direct rendering (by passing the wid of the widget) which draws the video overtop at that geometry:
you need to use offscreen rendering and draw that to your qwidget. this can be done with an opengl context (complicated) or using the callback methods available in libvlc.
if you use the display callback (libvlc_video_display_cb) libvlc will also generate lock/unlock methods also, if you need. in this method libvlc will expect some parameters to be set such as canvas geometry and pixel format.
that said, phonon has a libvlc backend which might help, but may still use direct rendering depending on some factors..