在播放视频的 QWidget 之上包含 QML 的 QDeclarativeView 的透明度(使用 phonon 或 libvlc)

发布于 2024-11-03 18:03:48 字数 2225 浏览 1 评论 0原文

我目前正在开发一个视频播放器。

最顶层的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);

两个元素,QDeclarativeViewQWidget 嵌入在QMainWindow中,lowerLayer在upperLayer之前创建, upperLayerlowerLayer 透明。

问题:

只要 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

请远离我 2024-11-10 18:03:48

您还在为这个问题而奋斗吗?遗憾的是,我没有给你一个满意的答案。我能做的就是向您指出它不起作用的原因:

http://lists.trolltech.com/qt-interest/2007-02/thread01061-0.html

请参阅上面链接中的消息 #4。

我尝试了许多不同的方法来使用 Qt 在视频(特别是 Phonon::VideoPlayer)上进行透明绘画。到目前为止,我发现的唯一方法是将覆盖的 QWidget 设置为工具提示,执行类似的操作

pWidget->setWindowFlags(Qt::ToolTip)

取决于您想要执行的操作,这可能就足够了,但(在我看来)这充其量只是一种黑客攻击。我正在积极解决这个问题,如果我能找到某种解决方案,我一定会将其发布在这里。

祝你好运。

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

pWidget->setWindowFlags(Qt::ToolTip)

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.

白鸥掠海 2024-11-10 18:03:48

您正在使用直接渲染(通过传递小部件的宽度),该渲染在该几何图形上绘制视频:

libvlc_media_player_set_x_window

您需要使用离屏渲染并将其绘制到您的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:

libvlc_media_player_set_x_window

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..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文