根據搜索引擎的結果,要想實現QT下播放多媒體,一般有兩種方案:一種是使用第三方插件,好像叫Phonon;一種是使用QT自帶的QMediaplayer。
兩種方法各有利弊。使用第三方插件,則方便易用,封裝性和易用性都很突出,但是,它萬一不更新了,就成了一筆壞賬了;而使用QT自帶的QMediaplayer,可以享受QT團隊的持續升級和支持,但是這個特性據說是5.0版本才引入和被支持的。
項目使用的QT版本為5.4.2,所以,果斷采用QMediaPlayer。
實現功能:就是使用QT播放指定聲音,且讓該聲音循環播放。
最初實現方案如下:
/* 定義需要使用的媒體相關的變量 */
QMediaPlayer* m_mpLoop;
QMediaPlaylist* m_mplistLoop;
const QString s_strLoopFileName;/* 聲音文件名稱 */
m_mpLoop = new QMediaPlayer;
m_mplistLoop = new QMediaPlaylist;
初始化代碼
/* High CPU Usage code */
bool MyClass::InitMediaPlayer(QString strDataFileName, QMediaPlayer* const pstMediaPlayer,
QMediaPlaylist* const pstPlaylist)
{
bool bRet = false;
if (NULL != pstMediaPlayer && NULL != pstPlaylist)
{
bRet = true;
/* s_strDataLoc表示當前音樂文件所在文件夾路徑(絕對路徑或相對路徑均可) */
QFileInfo stFileInfo(s_strDataLoc + strDataFileName);
/* 先往列表中添加媒體文件 */
pstPlaylist->addMedia(QUrl::fromLocalFile(stFileInfo.absoluteFilePath()));
/* 設置播放列表中當前項的索引 */
pstPlaylist->setCurrentIndex(0U);
/* 設置當前列表的播放方式為單曲循環 */
pstPlaylist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
/* 將建好的播放列表與相應的播放器關聯起來 */
pstMediaPlayer->setPlaylist(pstPlaylist);
/* 可以設置當前播放器的音量大小百分比 */
pstMediaPlayer->setVolume(70);
}
return bRet;
}
采用如下方式調用:
/* 初始化播放列表 */
InitMediaPlayer(s_strLoopFileName, m_mpLoop, m_mplistLoop);
這樣調用之后,發現問題就出來了。在我的電腦上CPU占用率很低,在別人的某些電腦上CPU占用率異常的高,簡直不能忍受,什么鬼~~~
直覺告訴我,罪魁禍首一定是設置單曲循環的地方!怎么辦呢?無從下手啊,並不知道這個為什么某些高,某些不高,sigh~
不用它現成的東西,我只能另辟蹊徑了~
看到這個類自帶以下的Signals和Slots,我決定從它們下手!
Slots
void play()
void setMuted(bool muted)
void setPosition(qint64 position)
void setVolume(int volume)
void stop()
Signals
void positionChanged(qint64 position)
void mediaStatusChanged(QMediaPlayer::MediaStatus status)
那么問題來了,到底捕捉positionChanged事件呢,還是捕捉mediaStatusChanged事件呢?position變化太頻繁,到時候CPU還是可能會很高的,那么還是選用mediaStatus吧!
OK!那就捕捉mediaStatusChanged的事件,查看自帶定義的媒體文件狀態定義如下:
| Constant | Value | Description |
|---|---|---|
| QMediaPlayer::UnknownMediaStatus | 0 | The status of the media cannot be determined. |
| QMediaPlayer::NoMedia | 1 | The is no current media. The player is in the StoppedState. |
| QMediaPlayer::LoadingMedia | 2 | The current media is being loaded. The player may be in any state. |
| QMediaPlayer::LoadedMedia | 3 | The current media has been loaded. The player is in the StoppedState. |
| QMediaPlayer::StalledMedia | 4 | Playback of the current media has stalled due to insufficient buffering or some other temporary interruption. The player is in the PlayingState or PausedState. |
| QMediaPlayer::BufferingMedia | 5 | The player is buffering data but has enough data buffered for playback to continue for the immediate future. The player is in the PlayingState or PausedState. |
| QMediaPlayer::BufferedMedia | 6 | The player has fully buffered the current media. The player is in the PlayingState or PausedState. |
| QMediaPlayer::EndOfMedia | 7 | Playback has reached the end of the current media. The player is in the StoppedState. |
| QMediaPlayer::InvalidMedia | 8 | The current media cannot be played. The player is in the StoppedState. |
那么只需要捕捉EndOfMedia這個狀態就好了,到時候播放完了,就setPosition到0的位置,那么不就settled了么?
部分實現代碼如下:
void MyClass::SlotProcMediaStatusChangeLoop(QMediaPlayer::MediaStatus status)
{
if (status == QMediaPlayer::EndOfMedia)
{
emit setPosition(0);/*設置初始位置為0*/
emit play();/*繼續播放*/
}
}
Finally,經過我的實驗驗證,無論是在我的電腦,還是在同事的電腦上,CPU占用率都降下來了!Settled!Nice!
