[原创文章,转载请注明来源,方便查看本文更新]

这段时间需要用QT开发一个播放直播流的功能,能够播放各种格式的直播流,并且CPU占用率不要太高(可以占用GPU),这些是我们的目标。

直播流推流的技术进展在上一篇博客中已经提到了,目前我的能力范围内只能推送RTMP格式的链接,所以需要播放端能够解析这种格式的链接。

下面是一张自己做的图,对QT可调用的几种播放方面的开源库进行对比:

Stage1:QT原生播放方式:QT QMediaPlayer

这种方式有两个优点:

  1. 无需额外的库,直接可以使用且实现方式简单,已经有大量的例子
  2. CPU占用率低,主要使用GPU

缺点:

  1. 支持的视频格式少,跟具体运行在哪个操作系统上有关。在Windows上需要安装LAVFilter等解码器才能支持很多的播放格式
  2. 无法打开非HTTP格式开头的直播流链接

代码示例:

     QWidget wi;
QMediaPlayer* player = new QMediaPlayer(, QMediaPlayer::VideoSurface);
QVideoWidget* vw = new QVideoWidget;
QVBoxLayout* lay = new QVBoxLayout;
lay->addWidget(vw);
vw->setMinimumSize(, );
lay->setSizeConstraint(QLayout::SetMinimumSize);
wi.setLayout(lay); player->setVideoOutput(vw); QNetworkRequest req(QUrl("http://pull-g.kktv8.com/livekktv/100987038.flv")); QMediaContent c(req);
player->setMedia(c);
player->play();

Stage2:使用OpenCV进行播放

优点:

  1. 支持的播放格式多
  2. 相应的示例程序多

缺点:

  1. 虽然底层调用的也是ffmpeg的库,但是OpenCV是将收到的直播流转换成了一张一张的图片,然后再一张一张的图片按顺序播放出来的
  2. 没有使用GPU,只使用了CPU,会造成CPU占用率极高(实际测试中,总能占满CPU)
  3. 代码编写麻烦

Stage3:使用Qt-vlc方式

优点:

  1. 支持的格式众多
  2. 可以打开多种直播流链接

缺点:

  1. 编译时比较麻烦

上图是目前支持的平台,链接中都是编译过可以直接用的库,只需要配置到相应位置即可

(头文件和lib库在QT的.pro文件中添加进去即可,DLL库需要将相应路径添加到系统环境变量中,具体可以参考:QT总结第3篇:如何在QT中添加.lib,.dll还有.h文件)

综合来说较为推荐

Stage4:使用FQFlib方式

在VLC没配置成后,就搜索"qt rtmp",找到了这个项目。这是一个正在成长中的项目,发布日期为2018年4月3日,距离现在仅有11天。主要是为了实现基于FFmpeg的rtsp/rtmp网络流媒体播放库。

作者仅给出了相应的库文件,以及一个基于QT的可运行在Visual Studio中的例子。

在经过尝试使用VS运行失败后,还是决定使用最熟悉的QT Creator运行,然后仿照在VS平台的例子,自己修改出来了一个例子,见GITHUB仓库

但是这个例子可以解析HTTP的直播链接,如CCTV1的:http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8

对于RTMP的链接,虽然可以加载,但是总是无法解析,遂放弃FQFlib的方式,继续寻找新方式。于是找到了QT-AV。

Stage5: Qt-AV开源项目

官方介绍:

QtAV is a multimedia playback library based on Qt and FFmpeg. It can help you to write a player with less effort than ever before.

QtAV has been added to FFmpeg projects page http://ffmpeg.org/projects.html

这个项目是2012年开始的,已经被ffmpeg官方收录了,的确是非常的方便。

下面简单写一下在Windows系统下的Qt-AV安装方式和使用方法,官方的文档在这里:https://github.com/wang-bin/QtAV/wiki/Build-QtAV,个人感觉没有说的很清楚,所以写一下自己踩过坑后的总结

1. 安装QT MSVC 2015 + VS2015

参考之前我的文章:http://www.cnblogs.com/QingHuan/p/7685328.html

2. 安装ffmpeg

下载链接:https://ffmpeg.zeranoe.com/builds/

将右边的Shared版本和Dev版本都下载下来,分别是DLL动态链接库、头文件和LIB。

头文件和lib库在QT的.pro文件中添加进去即可(第三步再进行添加),DLL库需要将相应路径添加到系统环境变量中,具体可以参考:QT总结第3篇:如何在QT中添加.lib,.dll还有.h文件

Windows系统的环境变量一般在重启后才会生效。

头文件和LIB文件的书写示例:

INCLUDEPATH += D:\ffmpeg\include
LIBS += -LD:\ffmpeg\lib -lavutil -lavformat -lavcodec -lswscale

3. 安装Qt-AV

  • 下载源代码:
git clone https://github.com/wang-bin/QtAV.git
git submodule update --init
  • 打开QtAV.pro,在Qt-Creator中将头文件和lib库在.pro文件中添加进去
  • 点击Build
  • 点击Run,如果出现下图则说明编译成功

  • 将编译后的库放在合适的位置,使QT-AV真正的作为库可以被调用

打开build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug文件夹,这个文件夹是和git clone之后的那个目录同级的,

找到sdk_install.bat,这个脚本能够自动将相应的DLL文件复制到正确的位置,可以看一下代码,很容易理解:

mkdir D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\*Qt*AV*.lib* D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\QtAV1.lib D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\Qt5AV.lib
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\QtAVd1.lib D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\Qt5AVd.lib
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\tools\install_sdk\mkspecs\features\av.prf D:\Qt\Qt5.7.1\5.7\msvc2015_64\mkspecs\features\av.prf
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\tools\install_sdk\mkspecs\modules\qt_lib_av*.pri D:\Qt\Qt5.7.1\5.7\msvc2015_64\mkspecs\modules\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\bin\Qt*AV*.dll D:\Qt\Qt5.7.1\5.7\msvc2015_64\bin\
mkdir D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAVWidgets\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\*Qt*AV*.lib* D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\QtAVWidgets1.lib D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\Qt5AVWidgets.lib
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\lib_win_x86_64\QtAVWidgetsd1.lib D:\Qt\Qt5.7.1\5.7\msvc2015_64\lib\Qt5AVWidgetsd.lib
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\tools\install_sdk\mkspecs\features\avwidgets.prf D:\Qt\Qt5.7.1\5.7\msvc2015_64\mkspecs\features\avwidgets.prf
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\tools\install_sdk\mkspecs\modules\qt_lib_avwidgets*.pri D:\Qt\Qt5.7.1\5.7\msvc2015_64\mkspecs\modules\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\bin\Qt*AV*.dll D:\Qt\Qt5.7.1\5.7\msvc2015_64\bin\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\src\QtAV\*.h D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\src\QtAV\QtAV D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\widgets\QtAVWidgets\*.h D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAVWidgets\
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\widgets\QtAVWidgets\QtAVWidgets D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAVWidgets\
mkdir D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\5.7.\QtAV\
xcopy /s /q /y /i C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\src\QtAV\private D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\private
xcopy /s /q /y /i C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\src\QtAV\private D:\Qt\Qt5.7.1\5.7\msvc2015_64\include\QtAV\5.7.\QtAV\private
xcopy /s /q /y /i C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\build-QtAV-Desktop_Qt_5_7_1_MSVC2015_64bit-Debug\bin\QtAV D:\Qt\Qt5.7.1\5.7\msvc2015_64\qml\QtAV
copy /y C:\Users\Bert\Documents\Qt_Project\qt-ffmpeg\QtAV\tools\install_sdk\..\..\qml\plugins.qmltypes D:\Qt\Qt5.7.1\5.7\msvc2015_64\qml\QtAV\

此时就可以使用所有QT-AV的例子了,也可以创造自己的新工程并调用它。

注意:在DEBUG模式下编译的QT-AV只能让同样在DEBUG模式下编译的工程使用,

如果你想要使用windeployqt来打包你的程序(即生成绿色无安装版本程序),需要将QT-AV和你自己的工程都在QT Creator的release模式下进行编译。

更多关于使用windeployqt来打包程序的细节不在此赘述。我已经将自己打包的一个程序发布在了GITHUB上,可以参考一下:https://github.com/zhixuanli/qt-av-stream-player

4. 打开一个播放视频的程序并改造它

切换当前目录到如下位置:

\QtAV\examples\simpleplayer

点击打开simpleplayer_sdk.pro来在QT Creator中打开这个工程,不要打开simpleplayer.pro;

然后找到playerwindow.cpp,将68行进行如下修改,即可打开指定直播流链接(任意ffmpeg支持的格式,RTMP也支持),而非从本地加载一个视频

 //    QString file = QFileDialog::getOpenFileName(0, tr("Open a video"));
QString file = "rtmp://live.hkstv.hk.lxdns.com/live/hks";

再编译-运行,点击open即可打开香港位置的这个RTMP格式的直播流

相应的源代码和绿色版程序已经放在了我的仓库里:https://github.com/zhixuanli/qt-av-stream-player

5. 站在Qt-AV的角度看FQFlib

Qt-AV其实已经完成了FQFlib所要开发的对RTMP和RSTP格式直播流播放的支持,而且根据目前的实际测试其并不能播放RTMP(也可能是我自己没写好)

但是在已经有轮子的情况下,不太建议FQFlib的作者继续重新造轮子

RTMP测试源:rtmp://live.hkstv.hk.lxdns.com/live/hks

RTSP测试源:rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov

多说一点:

HTTP和RTMP是直播流链接的格式,而直播流本身也有编码格式和封装格式。编码格式如h.264格式(也叫MPEG-4)等;封装格式则为MP4、WMV、FLV等。具体可以在推流时使用不同的ffmpeg参数进行设置。

H.264的维基百科介绍:

H.264,又称为MPEG-4第10部分,高级视频编码(英语:MPEG-4 Part 10, Advanced Video Coding,缩写为MPEG-4 AVC)是一种面向块,基于运动补偿的视频编码标准(英语:Video_coding_format) 。

MP4和MPEG4并不同:参考自:Difference between MPEG4 and MP4

Key difference: MPEG-4 is a method of defining compression of audio and visual digital data. MPEG-4 can be used for compression of AV data for web, as used for streaming media, for CD distribution, as well as for voice broadcast television applications. The MP4 is a container format. This means that it can be used to store audio and/or video data.

总结

综合来说,Qt-AV给我留下的印象最好,其经过了6个年头的发展,也有了多次的版本迭代,已经较为完善。

如果您想要使用QT开发功能强大,支持播放“格式”众多且代码简单的播放器,非常推荐使用Qt-AV

本文写于2018年4月14日,信息具有时效性~

QT | 聊聊QT与直播流播放——从QMediaPlayer到Qt-AV的更多相关文章

  1. 抛开flash,自己开发实现C++ RTMP直播流播放器

    抛开flash,自己开发实现C++ RTMP直播流播放器 众所周知,RTMP是以flash为客户端播放器的直播协议,主要应用在B/S形式的场景中.本人研究并用C++开发实现了RTMP直播流协议的播放器 ...

  2. 各种RTMP直播流播放权限_音视频_数据花屏_问题检测与分析工具EasyRTMPClient

    之前的一篇博客<网络摄像机IPCamera RTSP直播播放网络/权限/音视频数据/花屏问题检测与分析助手EasyRTSPClient>,我们介绍了RTSP流的检测和分析工具EasyRTS ...

  3. 搭建rtmp直播流服务之4:videojs和ckPlayer开源播放器二次开发(播放rtmp、hls直播流及普通视频)

    前面几章讲解了使用 nginx-rtmp搭建直播流媒体服务器; ffmpeg推流到nginx-rtmp服务器; java通过命令行调用ffmpeg实现推流服务; 从数据源获取,到使用ffmpeg推流, ...

  4. UWP 播放直播流 3MU8

    UWP 播放直播流 3MU8 参考:http://www.c-sharpcorner.com/UploadFile/2b876a/http-live-streaming-in-windows-10-u ...

  5. 利用Docker挂载Nginx-rtmp(服务器直播流分发)+FFmpeg(推流)+Vue.js结合Video.js(播放器流播放)来实现实时网络直播

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_75 众所周知,在视频直播领域,有不同的商家提供各种的商业解决方案,其中比较靠谱的服务商有阿里云直播,腾讯云直播,以及又拍云和网易云 ...

  6. ffmpeg推送直播流的技术进展

    首先安装好NGINX并打开服务 然后安装好ffmpeg 然后参考:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=2879051 ...

  7. 实现输出h264直播流的rtmp服务器

    RTMP(Real Time Messaging Protocol)是常见的流媒体协议,用来传输音视频数据,结合flash,广泛用于直播.点播.聊天等应用,以及pc.移动.嵌入式等平台,是做流媒体开发 ...

  8. 实现输出h264直播流的rtmp服务器 flash直播服务器【转】

    实现输出h264直播流的rtmp服务器 RTMP(Real Time Messaging Protocol)是常见的流媒体协议,用来传输音视频数据,结合flash,广泛用于直播.点播.聊天等应用,以及 ...

  9. 实现输出h264直播流的rtmp服务器 flash直播服务器

    http://www.cnblogs.com/haibindev/archive/2012/04/16/2450989.html 实现输出h264直播流的rtmp服务器 RTMP(Real Time ...

随机推荐

  1. PDF 补丁丁 0.6.0.3340 版发布(修复提取图片的问题)

    新的版本修复了两个导致提取图片颜色异常的问题.

  2. lr_场景设计之组场景、nmon监控

    1.组场景常用于回归 ,可以设置成一个脚本后多久运行下一个脚本: Real-world Schedule和Basic schedule的区别:根据官方文档,这两种模式下,场景中的每个虚拟用户组(可看成 ...

  3. MySQL · 性能优化· 5.7.6 InnoDB page flush 优化

    在这篇文中,我们已经详细介绍了Oracle MySQL以及社区分支最新的对InnoDB page flush的优化.在最近release的5.7.6版本中又有了进一步的改进.主要包括以下几点修改 修改 ...

  4. Idea中:No converter found for return value of type: class java.util.ArrayList:Json格式转换问题

    1.在搞SSM框架的时候,前端发送请求后,显示如下错误. @ResponseBody注解进行返回List<对象>的json数据时出现 nested exception is java.la ...

  5. 如何用EFCore Lazy Loading实现Entity Split

    α角 与 β角 支持 现实生活 的 计算机系统,总有着两大偏差,第一个是 现实生活 与 计算机系统 的α角,另外一个是计算机系统的 逻辑设计 与 物理设计 的β角.举个栗子: α角:假设某个公司的商业 ...

  6. Java线程面试题Top50

    不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java 语言一个重要的特点就是内置了对并发的支持,让 Java 大受企业和程序员的欢迎.大多数待遇丰厚的 Java 开发职位都要求开发者 ...

  7. pgmpy安装

    1.anaconda安装,可能在cmd中输入conda会报错,是因为在安装的时候没有配置好环境变量,在安装的时候有一个框框没选(当时是not recommand), 解决办法:需要在系统环境变量中添加 ...

  8. COPD——团队项目测试心得

    写在前面: 测试结束了,也要和项目说拜拜了~这一学期时间飞快,痛并快乐着,想想人生如果是个软件,那我们用多长时间在做测试呢?恐怕是一辈子.很多人忙着追逐,却很少人能停下来审视自己,那些时常自省的,常能 ...

  9. 后台管理系统之“图片上传” --vue

    图片上传(基于vue) 相信上传图片是所有系统必备的功能吧,工作中的第一个管理系统就在上传图片的功能上卡顿了一整天. 当时用的elementUI组件,但是由于样式和设计图样式差别较大再加上原生相较好理 ...

  10. struts2之数据校验

    概述 在提交表单数据时,如果数据需要保存到数据库,空输入等可能会引发一些异常,为了避免引起用户的输入引起底层异常,通常在进行业务逻辑操作之前,先执行基本的数据校验. 下面通过四种方式来阐述Struts ...