Phonon video not displaying in QML through QGraphicsProxyWidget
-
Hi,
I am trying to get a phonon video (which I know already displays properly in Qt as a regular VideoWidget) to display in QML. I have followed examples for placing Qt Widgets in QML using the QGraphicsProxyWidget, which I know works, since I can display other widgets like buttons in the QML when I set them as the QGraphicsProxy's widget. However, when I try to display the phonon video in the QML, I only get a black box where the video should be streaming. I would greatly appreciate if anyone could tell me what is going wrong with the ordering or declaration of the video that causes it to not be correctly displayed. I have tried following this example to the T, but it did not work http://kunalmaemo.blogspot.com/2011/08/using-phonon-video-player-from-qml.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/kunalmaemo+(Qt,+Maemo+and+other+stuff). My own code below get the video box into QML, but with no video coming through:
Main.cpp
@
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include <QDeclarativeItem>
#include <QGraphicsProxyWidget>
#include "streamer.h"Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
qmlRegisterType<Streamer>("CustomComponents", 1, 0, "Streamer");
viewer.setMainQmlFile(QLatin1String("qml/Test/main.qml"));
viewer.showExpanded();
return app->exec();
}
@
Streamer.h
@
#ifndef STREAMER_H
#define STREAMER_H#include <QDeclarativeItem>
#include <QGraphicsProxyWidget>
#include <Phonon/MediaSource>
#include <Phonon/VideoWidget>
#include <Phonon/MediaObject>
#include <Phonon/VideoPlayer>
#include <QDeclarativeImageProvider>class Streamer : public QDeclarativeItem
{
Q_OBJECT
Q_PROPERTY(QString source READ getSource WRITE setSource)
public:
Streamer(QDeclarativeItem *parent = 0);
Q_INVOKABLE void play();
virtual ~Streamer();private:
Phonon::VideoWidget* vidWid;
Phonon::MediaObject* mediaObj;
QGraphicsProxyWidget* proxy;
QString source;
};QML_DECLARE_TYPE(Streamer)
#endif // STREAMER_H
@
Streamer.cpp
@
#include "streamer.h"
#include <QGraphicsProxyWidget>
#include <Phonon/MediaSource>
#include <Phonon/VideoWidget>
#include <Phonon/MediaObject>
#include <Phonon/VideoPlayer>Streamer::Streamer(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
// Important, otherwise the paint method is never called
this->setFlag(QGraphicsItem::ItemHasNoContents, false);
mediaObj = new Phonon::MediaObject(this);
vidWid = new Phonon::VideoWidget();
Phonon::createPath(mediaObj, vidWid);
Phonon::MediaSource medSrc("v4l2://///dev/video2");
mediaObj->setCurrentSource( medSrc );
mediaObj->play();
proxy = new QGraphicsProxyWidget;
proxy->setWidget(vidWid);
proxy->setParentItem(this);
proxy->setVisible(true);
proxy->setPos(50, 50);proxy->show();
}
Streamer::~Streamer(){
delete proxy;
delete mediaObj;
delete vidWid;
}void Streamer::play(){
qDebug() << "Here";
mediaObj->play();
vidWid->show();
}
@
Qml
@
Rectangle{
color: "red"
Streamer{
id: videoStreamer
anchors.fill: parent
anchors.centerIn: parent
x: 200
y: 200
}
Rectangle {
id: rect
anchors.centerIn: parent
width: 100
height: 100
color: "blue"
MouseArea {
anchors.centerIn: parent
anchors.fill: parent
onClicked: {
videoStreamer.play()
}
}
}
}
@I originally tried just having the mediaObject play once the source was set, but that didn't work. So, I tried having it start playing after a click in the QML. Unfortunately, that didn't work either.
Thanks in advance for your thoughts
-
I've managed to get the video to play, but for some reason it is not correctly positioned. I'm still working on that, but this is the code:
@// QML:
Rectangle {
id: parentRect
width: 100
height: 200
color: "red"
//anchors.fill: parentQmlVideo{ id: theVideo width: 500 height: 600 } function playVideo( videoId ){ theVideo.play( videoId ); }
}
// C++ - class QmlVideo:
#include <QDeclarativeItem>
#include "VideoWidget.h"class QmlVideo : public QDeclarativeItem
{
Q_OBJECT
public:
explicit QmlVideo(QDeclarativeItem *parent = 0);signals:
public slots:
void play( const QString& strVideoId );
private:
VideoWidget* m_pVideoWidget;
};#include "QmlVideo.h"
#include <QGraphicsProxyWidget>
#include <QLabel>QmlVideo::QmlVideo(QDeclarativeItem parent)
: QDeclarativeItem(parent)
{
m_pVideoWidget = new VideoWidget;
QGraphicsProxyWidget proxy = new QGraphicsProxyWidget(this);proxy->setWidget(m_pVideoWidget);
}void QmlVideo::play( const QString& strVideoId )
{
m_pVideoWidget->play( strVideoId );
}// Class VideoWidget:
#include <QWidget>
#include <phonon/audiooutput.h>
#include <phonon/mediaobject.h>
#include <phonon/videowidget.h>class VideoWidget : public QWidget
{
Q_OBJECT
public:
explicit VideoWidget(QWidget *parent = 0);void play( const QString& strVideoId );
void playFile( QString filePath );signals:
public slots:
void stateChanged( Phonon::State newState, Phonon::State oldState );
void finished( );
void hasVideoChanged( bool );private:
QWidget m_videoWindow;
Phonon::MediaObject m_MediaObject;
Phonon::AudioOutput m_AudioOutput;
Phonon::VideoWidget* m_videoWidget;
Phonon::Path m_audioOutputPath;
};#include "videowidget.h"
#include <QtGui>
#include <QUrl>
#include <QVBoxLayout>
#include <phonon/MediaObject>VideoWidget::VideoWidget(QWidget parent)
: QWidget(parent)
, m_AudioOutput(Phonon::VideoCategory)
, m_videoWidget(new Phonon::VideoWidget(this))
{
QVBoxLayout vLayout = new QVBoxLayout(this);
vLayout->setContentsMargins(8, 8, 8, 8);QVBoxLayout* videoLayout = new QVBoxLayout();
videoLayout->addWidget(m_videoWidget);
videoLayout->setContentsMargins(0, 0, 0, 0);
m_videoWindow.setLayout(videoLayout);
m_videoWindow.setMinimumSize(100, 100);vLayout->addWidget(&m_videoWindow);
m_videoWindow.hide();setLayout(vLayout);
connect(&m_MediaObject, SIGNAL(finished()), this, SLOT(finished()));
connect(&m_MediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(stateChanged(Phonon::State,Phonon::State)));
// connect(&m_MediaObject, SIGNAL(bufferStatus(int)), this, SLOT(bufferStatus(int)));
connect(&m_MediaObject, SIGNAL(hasVideoChanged(bool)), this, SLOT(hasVideoChanged(bool)));m_audioOutputPath = Phonon::createPath( &m_MediaObject, &m_AudioOutput );
Phonon::createPath( &m_MediaObject, m_videoWidget );
}void VideoWidget::stateChanged( Phonon::State newstate, Phonon::State oldstate )
{
Q_UNUSED(oldstate);if (oldstate == Phonon::LoadingState) { QRect videoHintRect = QRect(QPoint(0, 0), m_videoWindow.sizeHint()); QRect newVideoRect = QApplication::desktop()->screenGeometry().intersected(videoHintRect); { if (m_MediaObject.hasVideo()) { // Flush event que so that sizeHint takes the // recently shown/hidden m_videoWindow into account: qApp->processEvents(); resize(sizeHint()); } else resize(minimumSize()); } } switch (newstate) { case Phonon::ErrorState: if (m_MediaObject.errorType() == Phonon::FatalError) { } else { m_MediaObject.pause(); } QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close); break; case Phonon::StoppedState: m_videoWidget->setFullScreen(false); // Fall through!!!! case Phonon::PausedState: if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){ } else { } break; case Phonon::PlayingState: if (m_MediaObject.hasVideo()) m_videoWindow.show(); // Fall through case Phonon::BufferingState: break; case Phonon::LoadingState: break; }
}
void VideoWidget::play( const QString& strVideoId )
{
QString sourceFile = "./path/to/videos/" + strVideoId + ".wmv";
playFile( sourceFile );
}void VideoWidget::playFile( QString filePath )
{
m_MediaObject.setCurrentSource(Phonon::MediaSource(filePath));
m_MediaObject.play( );
}void VideoWidget::finished()
{
}void VideoWidget::hasVideoChanged(bool bHasVideo)
{
m_videoWindow.setVisible(bHasVideo);
}
@