QT:在QVideoWidget中获取视频尺寸

QT: get video dimensions in QVideoWidget

这应该很简单,但我想不通。如何获取加载到 QVideoWidget/QMediaPlayer 中的文件的视频尺寸。所以,我的代码如下:

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. 

}

理论上有两种方法可以获取这些信息:

  1. 通过 QMediaPlayer::metaData using the key Resolution 你应该得到 QSize:

    的分辨率
    if (m_MediaPLayer->isMetaDataAvailable()) {
      qDebug() <<"resolution:"  <<m_MediaPLayer->metaData("Resolution");
    }
    
  2. 使用 QMediaResource.resolution() 也 returns 一个 QSize:

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

然而,在这两种情况下,对于我尝试的两个视频(一个 avi 和一个 mp4),它 returns -1,-1

有一些关于此问题的旧 Qt 线程: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 其中:

QTBUG-28850 - QMediaResource returns no media info

仍在营业。

一些相关问题:

  • Get native video resolution of a video file
  • C++ : What's the easiest library to open video file
  • How to read video metadata (C/C++)?

一个 answer in the last question suggests to use MediaInfo,其中包含可以提取视频元数据的库。

我预计 OpenCV to be able to do this, however this is not the case

我通过将 QVideoWidget 替换为 QGraphicsView + QGraphicsVideoItem 解决了这个问题。 QGraphicsVideoItemnativeSize 属性。但棘手的是 nativeSize 仅在您开始播放视频一段时间后才生效。诀窍是连接到特殊的 QGraphicsVideoItem::nativeSizeChanged(const QSizeF &size) 信号,该信号在真正 nativeSize 获得的情况下发出。

代码示例:

 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);