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: parent

    QmlVideo{
        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);
    }
    @



  • It is just a little hack but to have the position for the video origin in the upper left corner use in qml:

    @
    QmlVideo {
    id: videoID
    x: -485
    y: -350
    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.