Here is my code:
QString BoatProgramming::setDuration(QString path)
{
if (path.isNull()) { return ""; }
QMediaPlayer mp;
mp.setMedia(QUrl::fromLocalFile("/home/akiva/deleteme.ogg"));
qDebug() << mp.duration(); // Outputting a value of -1
m_Duration = QString::number(mp.duration());
emit durationChanged();
return m_Duration;
}
There is obviously an error somewhere, but beyond checking the filename, I am lamentably amiss as to what the problem is. Could it be simply that .ogg
is not supported? Am I calling the function before the object is fully loaded into memory? Or is it something else?
Thanks.
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()
anderror()
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();
}