Use QML VideoOutput item with C++ QMediaPlayer?



  • Hi,

    is it possible to render video from the C++ class QMediaPlayer in Quick2's VideoOutput item?

    I need to use real c++ features like the QVideoProbe, but still display via the Quick2 engine. I have tried to expose the QMediaPlayer object to QML like so,

    @QMediaPlayer player;
    QQuickView view;
    view.engine()->rootContext()->setContextProperty("mediaplayer", &player);
    @

    and then use it in QML like this:

    @ VideoOutput {
    id: videooutput
    width: 320
    height: 240
    source: mediaplayer
    }@

    But that does not seem to work, no video and no error message. Same code works with the QML MediaPlayer as source though.

    Thanks!



  • You have to extend QMediaPlayer.

    Look at this from qdeclarativevideooutput.cpp source code:
    @
    /*
    \qmlproperty variant QtMultimedia::VideoOutput::source

    This property holds the source item providing the video frames like MediaPlayer or Camera.

    If you are extending your own C++ classes to interoperate with VideoOutput, you can either provide a QObject based class with a \c mediaObject property that exposes a QMediaObject derived class that has a QVideoRendererControl available, or you can provide a QObject based class with a writable \c videoSurface property that can accept a QAbstractVideoSurface based class and can follow the correct protocol to deliver QVideoFrames to it.
    */
    @

    So, if you do like this:

    MyMediaPlayer.h
    @
    #include <QMediaPlayer>

    class MyMediaPlayer: public QMediaPlayer
    {
    Q_OBJECT
    Q_PROPERTY(QAbstractVideoSurface* videoSurface READ getVideoSurface WRITE setVideoSurface )

    public:
    MyMediaPlayer(QObject * parent = 0, Flags flags = 0);

    public slots:

    void setVideoSurface(QAbstractVideoSurface surface);
    QAbstractVideoSurface
    getVideoSurface();

    private:
    QAbstractVideoSurface* m_surface;
    };
    @

    MyMediaPlayer.cpp
    @
    #include "MyMediaPlayer.h"
    MyMediaPlayer::MyMediaPlayer(QObject* parent, Flags flags): QMediaPlayer(parent, flags)
    {
    }

    void MyMediaPlayer::setVideoSurface(QAbstractVideoSurface* surface)
    {
    qDebug() << "Changing surface";
    m_surface = surface;
    setVideoOutput(m_surface);
    }

    QAbstractVideoSurface* MyMediaPlayer::getVideoSurface()
    {
    return m_surface;
    }
    @

    then:
    @
    MyMediaPlayer* player = new MyMediaPlayer();
    QQuickView view;
    view.engine()->rootContext()->setContextProperty("mediaplayer", player);
    @

    your qml:
    @
    VideoOutput {
    id: videooutput
    width: 320
    height: 240
    source: mediaplayer
    }
    @

    It works. I've just tested it with Qt 5.2



  • Hi laureon, I am interested in trying your method. How can i specify the video source of the mediaplayer. do i use QUrl? put it in the .cpp file? or the qml side?

    thanks



  • From CPP you do:
    @
    player->setMedia(QUrl::fromLocalFile("THE PATH TO YOU MEDIA FILE"));
    player->play();
    @



  • I see, it worked for me. But any idea how can i trigger the "player->play()" from inside qml?



  • In your MyMediaPlayer.h put something like this under public slots:

    @
    virtual void play(const QString& strFile);
    @

    In your MyMediaPlayer.cpp goes
    @
    void MyMediaPlayer::play(const QString& strFile)
    {
    QMediaPlayer::setMedia(QUrl::fromLocalFile(strFile));
    QMediaPlayer::play();
    }
    @

    In your qml call: mediaplayer.play("PATH TO YOUR FILE")



  • Since i've been trying stuffs and not really putting it neatly, now whenever i play the media, only the audio working. What did i do wrong?

    this is my main.cpp:
    [CODE]
    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    qmlRegisterType<MyMediaPlayer>("videoPlayer",1,0,"VideoPlayer");
    
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile&#40;QStringLiteral("qml/tesVideoLaureon/main.qml"&#41;&#41;;
    viewer.showExpanded();
    
    
    MyMediaPlayer* player = new MyMediaPlayer();
    QQuickView view;
    view.engine()->rootContext()->setContextProperty("mediaplayer",player);
    //player->setMedia(QUrl::fromLocalFile&#40;"/users/...../Qt/intro.MP4"&#41;&#41;;
    //player->play();
    return app.exec&#40;&#41;;
    

    }
    [/CODE]

    and my main.qml:
    [CODE]

    Rectangle {
    id: rect
    width: 320; height: 240

    VideoPlayer{
        id:playa
    
    }
    VideoOutput {
            id: videooutput
            width: 320
            height: 240
            source: mediaplayer
            
    MouseArea {
        anchors.fill: parent
        onClicked: {
            playa.play("/users/......../Qt/intro.MP4")
            //console.log("playa triggered")
        }
    }
    }
    

    }

    [/CODE]



  • Hi , I was having the same problem , I did not implement AbstractVideoSurface but I was only having video
    have you solved the problem ?



  • Problem solved !



  • hi im getting
    qrc:/MediaPlayNew.qml:1044: ReferenceError: mediaplayer



  • Can you provide an example how to do it for first case?
    i.e

    If you are extending your own C++ classes to interoperate with VideoOutput, you can either provide a QObject based class with a \c mediaObject property that exposes a QMediaObject derived class that has a QVideoRendererControl available"
    

Log in to reply
 

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