Saturday, August 27, 2011

Using Phonon Video player from QML

Recently one of my friend asked me to give some sample code for integrating Phonon Video Player to QML. Long back I had created a application which download video from dailymotion and play the video using Phonon.

QtMultimediaKit provides QML Video element which we cause use for playing video. But form reason if you need to use your exiting code then you can follow what I did.

I tried to my video widget from that application with sample QML application. I was able to integrate that widget quite easily without any problem.

Following is sample code for video player that uses the Phonon VideoPlayer to play video.

#include <phonon/videoplayer.h>
#include <QUrl>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{    
    player = new Phonon::VideoPlayer(Phonon::VideoCategory, this);

    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    mainLayout->setMargin(0);
    mainLayout->addWidget( player);
}

void Widget::play()
{
    if( player->isPlaying() == false )
        player->play(QUrl("URL FOR VIDEO"));
}
Then I created an custom QDeclarativeItem, which uses my video widget class through QGraphicsProxyWidget. Visit my post for more information how we can use this class into QML.
#include "qmlvideo.h"
#include <QGraphicsProxyWidget>

#include "widget.h"

QmlVideo::QmlVideo(QDeclarativeItem *parent) :
    QDeclarativeItem(parent)
{
    myVideoWidget = new Widget;
    QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget(this);
    proxy->setWidget(myVideoWidget);
}


void QmlVideo::play()
{
    myVideoWidget->play();
}
Now finally I created QML file which uses above created declarative item. I also tried how we can put player control with video player. Following is final code with some unnecessary code removed.
import QtQuick 1.0
import qmlVideo 1.0

Rectangle {
    width: 624 ; height: 480
    QmlVideo{
        id:videoPlayer
    }

    Item{
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        width: playerControl.width
        height: playerControl.height
        MouseArea{
            id:mouseArea
            anchors.fill: parent
            hoverEnabled:true

            onEntered: {
                playerControl.opacity = 1
            }

            onExited: {
                playerControl.opacity = 0
            }
        }
    }

    Rectangle{
        width: 200
        height: 50
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        id:playerControl
        color: "gray"
        opacity: 0
        radius:10

        Row{
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            spacing: 20

            Button{
                icon: "backward.png"
                iconOn:"backward_on.png"
                onClicked: {
                    videoPlayer.backward();
                }
            }
        }

        Behavior on opacity {
            NumberAnimation { duration: 500 }
        }
    }
}
Following is output and here is link to source code.Hope it will be useful to someone.

24 comments:

  1. Hi,
    I'm trying to test this solution, but my question is... may I control the about to finish signal from the video player?
    Because I need to know when the video is finished to play to hide the video widget from the screen...

    ReplyDelete
  2. Hi Dario,
    you can get mediaObject from VideoPlayer and then you can connect finished signal and other required signal.

    ReplyDelete
  3. Hello! thanks for this article? Could you share the whole project please?

    ReplyDelete
  4. sure, will add project to my git repo.

    ReplyDelete
  5. what is repo url? I have some questions but at first I want to see last version of source

    ReplyDelete
  6. I have not uploaded code yet, will try to upload soon.

    ReplyDelete
  7. Hi Kunal, I tested this solution but the video loss quality,why do this happens?

    ReplyDelete
  8. Your solution is a great help for me because I'm working on a project where this is necessary, but what anonymous says is true, when the application runs the video loss the original colors and the quality is poor. Please, I need an urgent solution.SOS.

    ReplyDelete
  9. Hi, Thank you for feedback. I never checked the video quality issue, as I never used it for any production code. I will try to identify what can cause this issue.

    ReplyDelete
  10. PLease send us the code

    ReplyDelete
  11. Unfortunately I am not able to find the code, I will upload as soon as I find it

    ReplyDelete
  12. any update on this. I cannot get it to work either. the best result I've had is sound only. I'm getting desperate here. (I'm building on windows 7, tried with visual 2008 and mingw.)

    ReplyDelete
    Replies
    1. The reason why you are getting only audio is that when you create an instance of the Widget (myVideoWidget = new Widget;) you pass null pointer as a parent window, in which case the instance is a window itself, however, it is not shown/visible.
      If you want to get it visible, you have to call 'show()' just after 'mainLayout->addWidget( player);' in Widget constructor. However, you will get another window, displaying the video itself (because of that null as a parent container).
      Give it a try :)

      Delete
    2. Hi Kunal, i hav tried your code, and i have the same problem too , i have put a show(); after mainLayout->addWidget( player); but it still has the sound only,ps i am playing in the wmv format , some how my other rmvb file does work at all and yours seems work

      Delete
  13. This comment has been removed by the author.

    ReplyDelete
  14. Please follow this bug. This is not fixed yet. https://bugreports.qt-project.org/browse/QTBUG-8737.

    Seems like the patch provided is solving the problem. But I have not verified myself.

    ReplyDelete
  15. where can i download this project??

    ReplyDelete
  16. Hi,
    Finally I was able to relocate my original code, here is link

    https://gitorious.org/kunaltest/kunaltest/trees/master/qmlVideo

    ReplyDelete
  17. Hi Kunal, i hav tried your code, and i have the same problem too , i have put a show(); after mainLayout->addWidget( player); but it still has the sound only,ps i am playing in the wmv format , some how my other rmvb file does work at all and yours seems work

    ReplyDelete
    Replies
    1. Please try to remove the layoutcomponent and leave player instance stand-alone + resize it, just like this - it helped me

      Widget::Widget(QWidget *parent)
      : QWidget(parent)
      {
      player = new Phonon::VideoPlayer(Phonon::VideoCategory, this);
      player->resize(624,480);
      /*
      QVBoxLayout* mainLayout = new QVBoxLayout(this);
      mainLayout->setMargin(0);
      mainLayout->addWidget( player);
      */
      }

      Delete
    2. Oh thanks so much , i am able to see the video now, but it doesnt sits in the middle i have resize the window to see the whole thing,its like the video sits in the right bottom 1/4 of the screen only like a square. could you help me out please

      Delete
  18. The video still has poor quality

    ReplyDelete
  19. This comment has been removed by a blog administrator.

    ReplyDelete