用QMediaPlayerControl播放AAC格式音频

VS2015+Qt5.9.1,需要播放AAC格式音频,用QMediaPlayer试了不行,其他格式的WMA,WAV,MP3试了都可以,怀疑是没有解码器,下载安装了K-Lite Codec Pack,果然可以了,但只是为了播放个AAC,犯不着给用户装个解码器,而且不装K-Lite之前,用Windows Media Player是可以播放AAC的,所以断定Windows自己是可以搞定的,遂卸载K-Lite。

然后了解到有人说QMediaPlayer的格式支持取决于系统的DirectShow,但我Windows Media Player可以播放啊,难道不是DirectShow支持的,郁闷。再然后又从Qt Multimedia on Windows了解到,Qt提供了两个封装好的插件,一个是使用Microsoft DirectShow API,另一个是使用WMF (Windows Media Foundation) framework。DirectShow自XP起被逐渐弃用,而WMF是从Vista开始新引入的。微软总是喜欢自我否定,那就直奔新引入的吧。其实后来也试了下DirectShow的插件,播放不了AAC。DirectShow插件源码里也有注释推荐WMF。

// The player service provided by the WMF-plugin should preferably be used.
// DirectShow should then only provide the camera (see QTBUG-29172, QTBUG-29175).

经过一番读文档、上网搜、猜想加实践,最后总算是走通了这条路。首先dll需要自己编,WMF的插件名字叫wmfengine.dll,项目wmf.pro(DirectShow,directshow.pro,dsengine.dll),文件位置本地自己搜索,我用的VS,导入pro前需要把pro里的qtConfig(wmf-player): include (player/player.pri)改为 include (player/player.pri)(好吧,直接这样改其实是我不知道怎么让qtConfig(wmf-player)为真,知道的望告知),不然只有MFAudioDecoderService的代码,没有包含进来MFPlayerService的代码。

qtConfig(wmf-player): include (player/player.pri)
include (decoder/decoder.pri)

然而想用Player,还得过代码里的一个关卡,因为#if QT_CONFIG(wmf_player)才会new player,最后发现这个宏是在qtmultimedia-config_p.h里定义的,需要把QT_FEATURE_wmf_player由-1改为1。

QMediaService* WMFServicePlugin::create(QString const& key)
{
#if QT_CONFIG(wmf_player)
    if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) {
        addRefCount();
        return new MFPlayerService;
    }
#endif
    if (key == QLatin1String(Q_MEDIASERVICE_AUDIODECODER)) {
        addRefCount();
        return new MFAudioDecoderService;
    }
    //qDebug() << "unsupported key:" << key;
    return 0;
}
//#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
//qtmultimedia-config_p.h

//...
#define QT_FEATURE_wmf_player 1
//...
编好后外部使用的核心简化代码。

#include <QPluginLoader>
#include <QMediaPlayerControl>
#include <QMediaServiceProviderPlugin> 

QPluginLoader loader("wmfengine.dll");
QObject *plugin = loader.instance();
QMediaServiceProviderPlugin *mediaServicePlugin = qobject_cast<QMediaServiceProviderPlugin *>(plugin);
QMediaService *mediaService = mediaServicePlugin->create(Q_MEDIASERVICE_MEDIAPLAYER);
QMediaPlayerControl *mediaControl = qobject_cast<QMediaPlayerControl *>(mediaService->requestControl(QMediaPlayerControl_iid));
QMediaContent media(QUrl::fromLocalFile("Voice.aac"));
mediaControl->setMedia(media, nullptr);
mediaControl->play();

//mediaService->releaseControl(mediaControl);
//mediaServicePlugin->release(mediaService);

OK,这样就可以播放AAC了,只是有个问题,QMediaPlayerControl的信号positionChanged看起来并不会给反馈,所以进度可能需要自己用QTimer来解决。

还有些其他疑问有待研究,没明白这个MFAudioDecoderService怎么使用?也不知道MFPlayerService能否播放视频,QMediaPlayerControl没有setVideoOutput的话,那视频输出到了哪里呢?有研究的可以分享下。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coye1023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值