在Windows下使用QMediaPlayer实现播放视频
一、QMediaPlayer介绍
QMediaPlayer是Qt提供的一个跨平台媒体播放器类。
该类,在Windows下时,底层基于微软的DirectShow框架实现;在Linux下时,底层基于GStreamer框架实现。
也就是说,Qt没有直接使用解码库,而是对平台相关的播放器框架做了封装,提供了平台无关的API。
本次测试是在Win平台,由于DirectShow框架的使用,是需要额外安装解码器的,故我们使用QMediaPlayer类时,也是需要借助解码器才能实现播放视频的。
二、调用QMediaPlayer实现播放视频
1、实现代码
我们创建一个Qt测试程序,在pro文件中添加如下内容,引入播放器、widgets模块
QT += multimedia multimediawidgets
否则,包含找不到如下头文件
#include <QMediaPlayer>
#include <QVideoWidget>
接下来,可以开始编码,实现一个简单播放视频的功能,代码非常的简单,如下。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMediaPlayer>
#include <QVideoWidget>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QMediaPlayer* player;
QVideoWidget* videoWidget;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 布局界面
videoWidget = new QVideoWidget();
delete centralWidget();
this->setCentralWidget(videoWidget);
// 设置视频文件,并播放程序所在目录下的video.mp4
player = new QMediaPlayer;
player->setVideoOutput(videoWidget);
player->setMedia(QUrl::fromLocalFile(qApp->applicationDirPath() + "/video.mp4"));
player->play();
}
MainWindow::~MainWindow()
{
delete player;
player = nullptr;
delete videoWidget;
videoWidget = nullptr;
delete ui;
}
以上代码主要用到了3个函数,setVideoOutput设置在哪个窗口上播放视频,setMedia设置需要播放的视频文件,最后调用play即可开始播放。
2、编译运行
我们编译运行,发现报错:
DirectShowPlayerService::doRender: Unresolved error code 0x80040266 (IDispatch error #102)
原因:前面我们说过需要额外安装解码器,QMediaPlayer才能正常工作,此错误,正是缺少解码器导致的。
解决办法:建议安装LAVFilters,下载地址:https://github.com/Nevcairiel/LAVFilters/releases
安装解码器后,播放成功,运行效果如下:
虽然播放成功,但是又出现了新的警告:
shell\osshell\lmui\ntshrui\dll\shrengine.cpp(1487)\ntshrui.dll!00007FFA2072FB9A: (caller: 00007FFA2075890F) ReturnHr(1) tid(2cd4) 80004005 未指定的错误
这个警告,貌似是在win10下才有的,与在win10下使用QFileDialog::getOpenFileName()函数就会输出警告类似,属于Qt的bug,目前一直没修复,不知道为什么,姑且就这样吧。
三、程序打包注意事项
如果需要把我们的程序进行打包,给客户安装使用,那么还需要引导客户额外安装LAVFilters,显得比较麻烦。接下来,介绍,如何将解码器打包进安装包。
1、QMediaPlayer找到解码器的原理
先来看看解码器,安装后的目录,如下:
可以看到,一堆dll、manifest和3个ax文件,我们只需要注册这3个ax文件,QMediaPlayer运行时,就可以根据注册信息找到解码器,并加载这些dll,那么就能解码视频,实现播放了。
注册ax文件:
regsvr32 /s LAVAudio.ax
regsvr32 /s LAVVideo.ax
regsvr32 /s LAVSplitter.ax
卸载ax文件:
regsvr32 /s /u LAVAudio.ax
regsvr32 /s /u LAVVideo.ax
regsvr32 /s /u LAVSplitter.ax
注意:
必须将ax和dll放在一起,否则即使注册后,也无法播放视频。另外注意,ax文件名称不要写错了,因为如果你输入任意的ax文件名,即便文件不存在,也不会提示注册错误。
明白了基本原理,就可以部署打包目录了。
2、部署打包目录
打包目录如下,其中包含程序、视频文件、解码器目录
解码器相关文件,放入LAVFilters文件夹中,如下:
其中新增的3个注册、3个卸载脚本文件,内容如下:
install_audio.bat
cd /d "%~dp0"
regsvr32.exe LAVAudio.ax
install_splitter.bat
cd /d "%~dp0"
regsvr32.exe LAVSplitter.ax
install_video.bat
cd /d "%~dp0"
regsvr32.exe LAVVideo.ax
uninstall_audio.bat
cd /d "%~dp0"
regsvr32.exe /u LAVAudio.ax
uninstall_splitter.bat
cd /d "%~dp0"
regsvr32.exe /u LAVSplitter.ax
uninstall_video.bat
cd /d "%~dp0"
regsvr32.exe /u LAVVideo.ax
这6个脚本文件,是从绿色版LAVFilters压缩包中获得,可直接下载:https://github.com/Nevcairiel/LAVFilters/releases/download/0.74.1/LAVFilters-0.74.1-x64.zip
打包的思路:
- 当安装结束后,自动执行install_audio.bat、install_splitter.bat、install_video.bat对ax文件进行注册,而后,程序运行起来,就可以正常解码;
- 当卸载程序前,自动执行uninstall_audio.bat、uninstall_splitter.bat、uninstall_video.bat对ax进行卸载。
如此,我们就将解码器一起打包了,一次安装,就可以正常使用程序。
本文涉及工程代码:
https://gitee.com/bailiyang/cdemo/tree/master/Qt/62QMediaPlayer/QMediaPlayer
若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!
同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。