Прозрачность QDeclarativeView, содержащего QML поверх QWidget, воспроизводящего видео (с использованием phonon или libvlc) - PullRequest
4 голосов
/ 27 апреля 2011

Я в настоящее время разрабатываю видеоплеер.

Графический интерфейс как самый верхний слой написан на 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.

Проблема:

Пока нижний слой отображает статические элементы, такие как изображение или некоторые цветныеформы, все работает отлично, полная прозрачность и функциональность.

Как только я начинаю отображать видео, такое как описанное *.ts, используя libvlc ИЛИ какое-то случайное видео, используя Phonon::VideoPlayer, частиupperLayer, расположенные над видео частями lowerLayer, отображаются цветом lowerLayer(default: gray), части upperLayer, расположенными над частями lowerLayer или другими, которые не содержат видеоэлементовотображаются в правильном поведении.

Вопрос:

Есть ли возможность и, если да, то как сделать верхний слой прозрачным, даже если воспроизводится видео?

Ответы [ 2 ]

3 голосов
/ 31 мая 2011

Вы все еще боретесь с этой проблемой?У меня, к сожалению, нет удовлетворительного ответа для вас.Лучшее, что я могу сделать, это указать вам причины, по которым это не работает:

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

См. Сообщение № 4 по ссылке выше.

Я пробовал много разных способов получить прозрачное рисование поверх видео (в частности Phonon :: VideoPlayer), используя Qt.Единственный метод, который я нашел до сих пор, это установить перекрывающий QWidget как всплывающую подсказку, выполняющую что-то вроде

pWidget->setWindowFlags(Qt::ToolTip)

В зависимости от того, что именно вы хотите сделать, этого может быть достаточно, но (помнение) это в лучшем случае взломать.Я активно борюсь с этой проблемой, и если я смогу найти какое-то решение, я обязательно опубликую его здесь.

Желаем удачи.

2 голосов
/ 13 апреля 2012

вы используете прямой рендеринг (передавая виджет виджета), который рисует видео поверх этой геометрии:

libvlc_media_player_set_x_window

вам нужно использовать закадровый рендеринг и рисовать его в своем qwidget.это можно сделать с помощью контекста opengl (сложный) или с помощью методов обратного вызова, доступных в libvlc.

, если вы используете обратный вызов дисплея (libvlc_video_display_cb), libvlc также будет генерировать методы блокировки / разблокировки, если вам это нужно.в этом методе libvlc будет ожидать установки некоторых параметров, таких как геометрия холста и формат пикселя.

при этом у phonon есть бэкэнд libvlc, который может помочь, но все же может использовать прямой рендеринг в зависимости от некоторых факторов ..

...