2016-11-30 3 views
0

Вот мой код:Почему QMediaPlayer :: duration() дает мне значение -1?

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 не поддерживается? Я вызываю функцию до того, как объект полностью загружен в память? Или что-то еще?

Спасибо.

ответ

1

QMediaPlayer::setMedia() выполняет Загрузка асинхронно, от docs:

Эта функция возвращает сразу после записи указанного источника средств массовой информации. Он не дожидался окончания загрузки и не проверял наличие ошибок. Слушайте сигналы 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(); 
} 
+0

Проблема для меня, я думаю, другая. Пробовав код в основном, все работает плавно, поэтому ваш код работает. Однако, пытаясь это сделать в своем классе, я могу подождать один год, и этот сигнал никогда не будет срабатывать. Вместо этого он изменил это: «QObject :: connect (& m_MediaPlayer, & QMediaPlayer :: durationChanged, [&] (qint64 fun)' работал. – Akiva

+0

Кстати, я пробовал искать его, но ради любви я не могу найти что-то на нем. Что делает синтаксис '[&]' do? Я никогда не видел ничего подобного. – Akiva

+1

@Akiva, это выражение лямбда C++ 11, см. [этот вопрос] (http://stackoverflow.com/q/7627098/2666212). Синтаксис '[&]' фиксирует переменные, используемые лямбдой по ссылке. ** ** НЕ выполняйте это для локальных переменных в методах вашего класса, вы в конечном итоге используете оборванные ссылки в ваш lambda (возможно, это причина для работы в основном, но не в вашем классе). Если вы не используете лямбда-выражения, используйте вместо этого обычный слот, чтобы избежать таких проблем (т. е. просто замените эту лямбда-функцию обычным слотом, определяется в вашем классе). – Mike

Смежные вопросы