August 2, 2012

bluestreak bluestreak
Lab Rat
33 posts

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

  1. #include <QtGui/QApplication>
  2. #include "qmlapplicationviewer.h"
  3. #include <QDeclarativeItem>
  4. #include <QGraphicsProxyWidget>
  5. #include "streamer.h"
  6.  
  7. Q_DECL_EXPORT int main(int argc, char *argv[])
  8. {
  9.     QScopedPointer<QApplication> app(createApplication(argc, argv));
  10.     QmlApplicationViewer viewer;
  11.     viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
  12.     qmlRegisterType<Streamer>("CustomComponents", 1, 0, "Streamer");
  13.     viewer.setMainQmlFile(QLatin1String("qml/Test/main.qml"));
  14.     viewer.showExpanded();
  15.     return app->exec();
  16. }

Streamer.h
  1. #ifndef STREAMER_H
  2. #define STREAMER_H
  3.  
  4. #include <QDeclarativeItem>
  5. #include <QGraphicsProxyWidget>
  6. #include <Phonon/MediaSource>
  7. #include <Phonon/VideoWidget>
  8. #include <Phonon/MediaObject>
  9. #include <Phonon/VideoPlayer>
  10. #include <QDeclarativeImageProvider>
  11.  
  12.  
  13. class Streamer : public QDeclarativeItem
  14. {
  15.     Q_OBJECT
  16.     Q_PROPERTY(QString source READ getSource WRITE setSource)
  17. public:
  18.     Streamer(QDeclarativeItem *parent = 0);
  19.     Q_INVOKABLE void play();
  20.     virtual ~Streamer();
  21.  
  22.  private:
  23.     Phonon::VideoWidget* vidWid;
  24.     Phonon::MediaObject* mediaObj;
  25.     QGraphicsProxyWidget* proxy;
  26.     QString source;
  27. };
  28.  
  29. QML_DECLARE_TYPE(Streamer)
  30.  
  31. #endif // STREAMER_H

Streamer.cpp
  1. #include "streamer.h"
  2. #include <QGraphicsProxyWidget>
  3. #include <Phonon/MediaSource>
  4. #include <Phonon/VideoWidget>
  5. #include <Phonon/MediaObject>
  6. #include <Phonon/VideoPlayer>
  7.  
  8. Streamer::Streamer(QDeclarativeItem *parent) :
  9.         QDeclarativeItem(parent)
  10. {
  11.     // Important, otherwise the paint method is never called
  12.     this->setFlag(QGraphicsItem::ItemHasNoContents, false);
  13.     mediaObj = new Phonon::MediaObject(this);
  14.     vidWid = new Phonon::VideoWidget();
  15.     Phonon::createPath(mediaObj, vidWid);
  16.     Phonon::MediaSource medSrc("v4l2://///dev/video2");
  17.     mediaObj->setCurrentSource( medSrc );
  18.     mediaObj->play();
  19.     proxy = new QGraphicsProxyWidget;
  20.     proxy->setWidget(vidWid);
  21.     proxy->setParentItem(this);
  22.     proxy->setVisible(true);
  23.     proxy->setPos(50, 50);
  24.  
  25.  
  26.     proxy->show();
  27. }
  28. Streamer::~Streamer(){
  29.     delete proxy;
  30.     delete mediaObj;
  31.     delete vidWid;
  32. }
  33.  
  34. void Streamer::play(){
  35.     qDebug() << "Here";
  36.     mediaObj->play();
  37.     vidWid->show();
  38. }

Qml
  1. Rectangle{
  2.     color: "red"
  3.     Streamer{
  4.         id: videoStreamer
  5.         anchors.fill: parent
  6.         anchors.centerIn: parent
  7.         x: 200
  8.         y: 200
  9.     }
  10.     Rectangle {
  11.        id: rect
  12.        anchors.centerIn: parent
  13.        width: 100
  14.        height: 100
  15.        color: "blue"
  16.        MouseArea {
  17.            anchors.centerIn: parent
  18.            anchors.fill: parent
  19.            onClicked: {
  20.                videoStreamer.play()
  21.            }
  22.        }
  23.     }
  24. }

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

2 replies

September 6, 2012

danielbsig danielbsig
Lab Rat
15 posts

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:

  1. // QML:
  2. Rectangle {
  3.     id: parentRect
  4.     width: 100
  5.     height: 200
  6.     color: "red"
  7.     //anchors.fill: parent
  8.  
  9.     QmlVideo{
  10.         id: theVideo
  11.         width: 500
  12.         height: 600
  13.     }
  14.  
  15.     function playVideo( videoId ){
  16.         theVideo.play( videoId );
  17.     }
  18. }
  19.  
  20.  
  21. // C++ - class QmlVideo:
  22.  
  23. #include <QDeclarativeItem>
  24. #include "VideoWidget.h"
  25.  
  26. class QmlVideo : public QDeclarativeItem
  27. {
  28.  Q_OBJECT
  29. public:
  30.  explicit QmlVideo(QDeclarativeItem *parent = 0);
  31.  
  32. signals:
  33.  
  34. public slots:
  35.    
  36.  void play( const QString& strVideoId );
  37.  
  38. private:
  39.  
  40.  VideoWidget*  m_pVideoWidget;
  41. };
  42.  
  43.  
  44. #include "QmlVideo.h"
  45. #include <QGraphicsProxyWidget>
  46. #include <QLabel>
  47.  
  48. QmlVideo::QmlVideo(QDeclarativeItem *parent)
  49.  : QDeclarativeItem(parent)
  50. {
  51.  m_pVideoWidget = new VideoWidget;
  52.  
  53.  proxy->setWidget(m_pVideoWidget);
  54. }
  55.  
  56. void QmlVideo::play( const QString& strVideoId )
  57. {
  58.  m_pVideoWidget->play( strVideoId );
  59. }
  60.  
  61.  
  62.  
  63. // Class VideoWidget:
  64.  
  65. #include <QWidget>
  66. #include <phonon/audiooutput.h>
  67. #include <phonon/mediaobject.h>
  68. #include <phonon/videowidget.h>
  69.  
  70. class VideoWidget : public QWidget
  71. {
  72.  Q_OBJECT
  73. public:
  74.  explicit VideoWidget(QWidget *parent = 0);
  75.  
  76.  void play( const QString& strVideoId );
  77.  void playFile( QString filePath );
  78.  
  79. signals:
  80.  
  81. public slots:
  82.  
  83.  void stateChanged( Phonon::State newState, Phonon::State oldState );
  84.  void finished( );
  85.  void hasVideoChanged( bool );
  86.  
  87. private:
  88.  
  89.  QWidget              m_videoWindow;
  90.  Phonon::MediaObject  m_MediaObject;
  91.  Phonon::AudioOutput  m_AudioOutput;
  92.  Phonon::VideoWidget* m_videoWidget;
  93.  Phonon::Path         m_audioOutputPath;
  94. };
  95.  
  96.  
  97.  
  98. #include "videowidget.h"
  99.  
  100. #include <QtGui>
  101. #include <QUrl>
  102. #include <QVBoxLayout>
  103. #include <phonon/MediaObject>
  104.  
  105. VideoWidget::VideoWidget(QWidget *parent)
  106.  : QWidget(parent)
  107.  , m_AudioOutput(Phonon::VideoCategory)
  108.  , m_videoWidget(new Phonon::VideoWidget(this))
  109. {
  110.  QVBoxLayout* vLayout = new QVBoxLayout(this);
  111.  vLayout->setContentsMargins(8, 8, 8, 8);
  112.  
  113.  QVBoxLayout* videoLayout = new QVBoxLayout();
  114.  videoLayout->addWidget(m_videoWidget);
  115.  videoLayout->setContentsMargins(0, 0, 0, 0);
  116.  m_videoWindow.setLayout(videoLayout);
  117.  m_videoWindow.setMinimumSize(100, 100);
  118.  
  119.  vLayout->addWidget(&m_videoWindow);
  120.  m_videoWindow.hide();
  121.  
  122.  setLayout(vLayout);
  123.  
  124.  connect(&m_MediaObject, SIGNAL(finished()), this, SLOT(finished()));
  125.  connect(&m_MediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(stateChanged(Phonon::State,Phonon::State)));
  126.  //    connect(&m_MediaObject, SIGNAL(bufferStatus(int)), this, SLOT(bufferStatus(int)));
  127.  connect(&m_MediaObject, SIGNAL(hasVideoChanged(bool)), this, SLOT(hasVideoChanged(bool)));
  128.  
  129.  m_audioOutputPath = Phonon::createPath( &m_MediaObject, &m_AudioOutput );
  130.  Phonon::createPath( &m_MediaObject, m_videoWidget );
  131. }
  132.  
  133. void VideoWidget::stateChanged( Phonon::State newstate, Phonon::State oldstate )
  134. {
  135.     Q_UNUSED(oldstate);
  136.  
  137.     if (oldstate == Phonon::LoadingState) {
  138.         QRect videoHintRect = QRect(QPoint(0, 0), m_videoWindow.sizeHint());
  139.         QRect newVideoRect = QApplication::desktop()->screenGeometry().intersected(videoHintRect);
  140.         {
  141.             if (m_MediaObject.hasVideo()) {
  142.                 // Flush event que so that sizeHint takes the
  143.                 // recently shown/hidden m_videoWindow into account:
  144.                 qApp->processEvents();
  145.                 resize(sizeHint());
  146.             } else
  147.                 resize(minimumSize());
  148.         }
  149.     }
  150.  
  151.     switch (newstate) {
  152.         case Phonon::ErrorState:
  153.             if (m_MediaObject.errorType() == Phonon::FatalError) {
  154.             } else {
  155.                 m_MediaObject.pause();
  156.             }
  157.             QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close);
  158.             break;
  159.  
  160.         case Phonon::StoppedState:
  161.             m_videoWidget->setFullScreen(false);
  162.             // Fall through!!!!
  163.         case Phonon::PausedState:
  164.             if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){
  165.             } else {
  166.             }
  167.             break;
  168.         case Phonon::PlayingState:
  169.             if (m_MediaObject.hasVideo())
  170.                 m_videoWindow.show();
  171.             // Fall through
  172.         case Phonon::BufferingState:
  173.             break;
  174.         case Phonon::LoadingState:
  175.             break;
  176.     }
  177. }
  178.  
  179. void VideoWidget::play( const QString& strVideoId )
  180. {
  181.  QString sourceFile = "./path/to/videos/" + strVideoId + ".wmv";
  182.     playFile( sourceFile );
  183. }
  184.  
  185. void VideoWidget::playFile( QString filePath )
  186. {
  187.     m_MediaObject.setCurrentSource(Phonon::MediaSource(filePath));
  188.     m_MediaObject.play( );
  189. }
  190.  
  191. void VideoWidget::finished()
  192. {
  193. }
  194.  
  195. void VideoWidget::hasVideoChanged(bool bHasVideo)
  196. {
  197.     m_videoWindow.setVisible(bHasVideo);
  198. }

September 20, 2012

MrPrust MrPrust
Lab Rat
1 posts

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

  1. QmlVideo {
  2. id: videoID
  3. x: -485
  4. y: -350
  5. }

 
  ‹‹ [Closed] How to Convert a QVariant to a QList<MyTypedef>      [SOLVED] How to retrieve data from a XmlListModel to another XmlListModel? ››

You must log in to post a reply. Not a member yet? Register here!