根据搜索引擎的结果,要想实现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,我决定从它们下手!
Slotsvoid play()
void setMuted(bool muted)
void setPosition(qint64 position)
void setVolume(int volume)
void stop()Signalsvoid 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!