QMediaPlayer::setMedia()
performs loading asynchronously, from the docs:
This function returns immediately after recording the specified source of the media. It does not wait for the media to finish loading and does not check for errors. Listen for the mediaStatusChanged()
and error()
signals to be notified when the media is loaded and when an error occurs during loading.
This means that querying QMediaPlayer
for duration()
after calling setMedia()
immediately may not work, since QMediaPlayer
might not have loaded the media yet.
In order to guarantee that loading has finished before calling duration()
, you have to listen for mediaStatusChanged()
signal, and get duration()
only when mediaStatus()
returns QMediaPlayer::LoadedMedia
. Here is a minimal example:
#include <QtWidgets>
#include <QtMultimedia>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QLabel label; //a label to display duration
QString fileName = QFileDialog::getOpenFileName(nullptr, "Open Media File");
QMediaPlayer mp;
mp.setMedia(QUrl::fromLocalFile(fileName));
QObject::connect(&mp, &QMediaPlayer::mediaStatusChanged,
[&](QMediaPlayer::MediaStatus status){
if(status == QMediaPlayer::LoadedMedia) //when loading is finished
{
//show duration in a label
qint64 duration= mp.duration();
label.setText(QString("Duration: %1 ms.\n\nThat is: %2")
.arg(duration)
.arg(QDateTime::fromTime_t(duration/1000).toUTC()
.toString("hh:mm:ss")));
label.show();
}
});
return app.exec();
}