QMediaPlayer占用CPU過高問題


根據搜索引擎的結果,要想實現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!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM