2016-11-30 68 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()信號。

這意味着立即調用setMedia()後查詢QMediaPlayerduration()可能無法正常工作,因爲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

順便說一句,我嘗試了使用Google搜索,但對於我的愛我無法找到任何關於它的語法''[&]'都做了什麼?我從來沒有見過這樣的東西。 – Akiva

+1

@Akiva,這是一個C++ 11 lambda表達式,請參閱[this question](http://stackoverflow.com/*/7627098/2666212)。[&]'語法通過引用捕獲lambda使用的變量。不要**在你的類的方法中爲局部變量做這些事情,你最終會使用dangling引用你的lambda(這可能是事情在main中工作的原因,但不在你的類中)如果你不習慣lambda表達式,使用普通的slot來避免這樣的問題(例如,用一個普通的slot替換lambda函數)在你的班級中定義) – Mike

相關問題