5

This should be something simple but I cannot figure this out. How can I get the video dimensions for a file that is loaded into QVideoWidget/QMediaPlayer. So, my code is as follows:

QMediaPlayer m_MediaPLayer(0, QMediaPlayer::VideoSurface);
m_VideoWidget = new QVideoWidget;
m_MediaPLayer.setVideoOutput(m_VideoWidget);
m_MediaPLayer.setMedia(QUrl::fromLocalFile("file.avi"));

m_MediaPLayer.play();
// I am here checking for media status changed event
connect(&m_MediaPLayer,   SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
        this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));

void MyClass::mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
    // Here I get notification for media status change but no idea how to 
    // get the video size. I could not figure out a way. 

}
Luca
  • 10,458
  • 24
  • 107
  • 234

2 Answers2

7

In theory there are two ways to get this information:

  1. Through QMediaPlayer::metaData using the key Resolution you should get the resolution as QSize:

    if (m_MediaPLayer->isMetaDataAvailable()) {
      qDebug() <<"resolution:"  <<m_MediaPLayer->metaData("Resolution");
    }
    
  2. Using QMediaResource.resolution() which also returns a QSize:

    qDebug() << "resolution:" << m_MediaPLayer->media().canonicalResource().resolution();
    

However, in both cases it returns -1,-1 for me for two videos I tried (one avi, and an mp4).

There are some old Qt threads about this problem: get resolution of a video file, and QMediaPlayer resolution returns (-1x-1). Although some solutions are given, none work for me, and in fact there is a bug report of this:

QTBUG-28850 - QMediaResource returns no media info

which is still open.

Some related questions:

An answer in the last question suggests to use MediaInfo, which contain libraries that can extract meta data of videos.

I expected OpenCV to be able to do this, however this is not the case.

Community
  • 1
  • 1
agold
  • 6,140
  • 9
  • 38
  • 54
  • 1
    The second version does not work for me but if I use the first version in the event handler for the QMediaPlayer::BufferedMedia status, it returns the correct size. I will make this wortk for me and thanks for the very detailed answer. – Luca Jan 20 '16 at 10:57
  • Ok, I'm glad to hear that! Just one question, which OS are you using? – agold Jan 20 '16 at 10:58
  • I am on Linux Mint 17, which is a fork of ubuntu 14.04, I think. I actually need to run it on an ARM based processor, so we will see how it goes later in the day but that is also running Ubuntu 14.04 (Tegra Jetson Tk1, NVIDIA). – Luca Jan 20 '16 at 11:43
  • Ok thanks, I am using Ubuntu 14.04, but it could be because of the videos I tried. – agold Jan 20 '16 at 11:53
  • I am using gstreamer 1.2.4 as well. Perhaps, it has something to do with the backend. Also, I am getting the size in the `mediaStatusChanged` signal event handler. This could also be a reason. – Luca Jan 20 '16 at 12:02
  • has anyone on osx gotten QMediaPlayer::metaData to return anything? – Neal Feb 15 '16 at 04:08
  • WMV & Windows 10 & Qt 5.10.1 got QSize(-1, -1). – JustWe Oct 02 '18 at 04:28
1

I've solved this problem by replacing QVideoWidget with QGraphicsView + QGraphicsVideoItem. QGraphicsVideoItem has nativeSize property. But the tricky thing is that nativeSize becomes valid only after some time since you start playing video. The trick is to connect to special QGraphicsVideoItem::nativeSizeChanged(const QSizeF &size) signal that is emitted in case of real nativeSize obtainment.

Code sample:

 m_player.setVideoOutput(&m_graphicsItem);    // m_player is QMediaPlayer
 ui->videoView->setScene(new QGraphicsScene); // videoView is QGraphicsView
 ui->videoView->scene()->addItem(&m_graphicsItem);

 connect(&m_graphicsItem, &QGraphicsVideoItem::nativeSizeChanged, this, &MainWindow::calcVideoFactor);
Nikolai Shalakin
  • 1,349
  • 2
  • 13
  • 25