Вот мой код:
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;
}
Очевидно, что где-то есть ошибка, но помимо проверки имени файла, я грустно не понимаю, в чем проблема. Может быть, это просто .ogg
не поддерживается? Я вызываю функцию до полной загрузки объекта в память? Или что-то еще?
Благодарю.
QMediaPlayer::setMedia()
выполняет загрузку асинхронно, из документы:
Эта функция возвращается сразу после записи указанного источника носителя. Он не ожидает окончания загрузки носителя и не проверяет наличие ошибок. Слушай
mediaStatusChanged()
а такжеerror()
сигналы для уведомления, когда носитель загружен и когда происходит ошибка во время загрузки.
Это означает, что запрос QMediaPlayer
за duration()
после звонка setMedia()
сразу может не сработать, т.к. QMediaPlayer
возможно, еще не загрузили носитель.
Чтобы гарантировать, что загрузка закончилась перед звонком duration()
, ты должен слушать mediaStatusChanged()
сигнал, и получить duration()
только когда mediaStatus()
возвращается QMediaPlayer::LoadedMedia
, Вот минимальный пример:
#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();
}
Других решений пока нет …