基于FFmpeg和Qt的播放器 QtAV库

参与项目开发: https://github.com/wang-bin/QtAV

下载编译好的文件等:https://sourceforge.net/projects/qtav

win下编译好的可执行文件及编译所需的文件在这:https://sourceforge.net/projects/qtav

win下编译要用到的库如ffmpeg,portaudio可以在https://sourceforge.net/projects/qtav/files/depends下载



2013.05.27 QtAV1.2.0发布:
更新很多东西,主要有
1. player例子加入gui界面,易于操控。自带一些网络电视
2. 独创的播放时渲染引擎无缝动态切换。可以方便地对比各种渲染引擎的cpu使用率
3. X11下XV的支持(Qt4 only)
4. bug修复等

基于FFmpeg和Qt的播放器 QtAV库_第1张图片

1.1.10还包含mac下的安装包。linux?不需要我编译把。
编译了个ubuntu1204上的:http://sourceforge.net/projects/qtav/files/QtAV%201.1.11/QtAV_1.1.11_ubuntu1204_i386.deb/download
需要装ffmpeg相关的libavcodec54等包,还要Qt。其实还是自己编译方便。而且现在支持直接

make deb

的方式来生成deb包了,不过我对包的结果不太了解,可能不太规范。
命令行:
player [-vo qt|gl|d2d|gdi] [url/path]filename
 或者把player改名成player-gl, player-d2d, player-gdi也可以


我ubuntu上初始化音频非常慢,不知是代码问题还是系统问题。。。


2013-03015
    新增了几个渲染方式,如opengl, direct2d, gdi。在我电脑上direct2d对性能提升非常明显。增加了OSD(现在的设计很烂),原来的O键改成了切换OSD。Ctrl+O是打开文件
    切换视频大小比例按R。
    完善了qmake的工程框架,移植了很多Qt5里qmake内置函数到Qt4,用qmake语法写的,支持编译检测。若要重新配置请删除编译目录里的.qmake.cache再qmake,mingw可能qmake一次不够,需要两次(还没找到原因,我的pro写得太复杂了)。linux下支持make deb来生成安装包。
    支持VC(我vs2010编译出来的无法运行,2012正常,不解),方法见github 上的wiki。支持Qt5


2013-02-28更新:

     windows下编译所需的FFmpeg和portaudio头文件和库文件放在了https://sourceforge.net/projects/qtav/files/depends

    支持MinGW和MSVC编译

    加入了几个windows下的渲染方法,修复了些bug,等等等等

    国内外有几个公司用到了我的项目。还有葡萄牙最古老的一所大学的一个博士在他的人机交互项目中也会使用,哈哈

2013-01-13更新:

    目前播放已经很稳定了,除了频繁seek有时会崩溃(还不知道为什么)。该项目已经有国外的几个开发者在使用了,比如有几个意大利的开发者就用它来显示摄像头的实时监控视频。我会把一些成功的案例贴在项目页面上。

    TODO: 组件化,某些组件实现硬件加速;外部时钟(保证无音频流也能正常播放);更优化的数据包队列结构;字幕;等等。。。



    很久以前就想用FFmpeg做个播放器,用Qt做gui。但是能力有限。网上大多数都是讲ffplay的,ffplay代码太长看着不舒服没花时间看。最近有个项目要用到视频播放功能,一开始用了phonon,用起来方便,但是有点不足,比如gui用的是QWidget的组件,我是希望用graphics framework ,自定义功能也不多。最重要的是我重装win8后不能工作,于是决定还是自己动手写个比较靠谱。知道原理之后发现并不难。

多线程

    其实总体思路还是比较简单的,用3个线程(除掉主线程),一个是分离器(demuxer)的线程,它的工作就是读取并分解音视频流,把数据包放到音/视频包的队列里。另外两个线程就是音频(播音频会阻塞)和视频解码播放线程了,它们的工作就是读取队列里的数据包进行解码,然后输出到窗口或音频设备。

同步

    看到网上讨论比较多的就是音视频同步,最开始其实我很傻地根据视频的帧率设置个timer,每隔多少个毫秒进行读取解码输出,也就一个线程,这个非常不精确。后来测试了下音频播放,发现不像视频那样循环得快了就播放速度变快,音频的播放速率最后会稳定到正常速度的(还不知道为什么,貌似要改变音频速率就要resample一下),怪不得别人经常说要把视频同步到音频。理解这点之后操作起来就非常简单了,音频解码的数据包里有个时间戳pts(有时候分离好后要处理下),播放这个包时记下这个时间戳,视频线程要播放视频包时时间戳和音频的对比下,快了就wait一下,慢了就赶紧播或者丢帧,这样处理后同步就没问题了。很简单,代码也很短,效果也很好。

缓冲

     还有一个要注意的是分离线程应该分离多少数据包,因为你让那个线程不停地跑的话一会儿整个视频就被读取光了,没必要,而且非常占内存,而你播放的时候并不需要那么多数据包。所以可以设置个缓冲,音视频包队列堆积到一定数量后就wait一下让解码播放线程继续跑一会,当队列里的数据包比较少的时候唤醒分离线程,叫它继续读取点数据。这样,可以把播放器的内存占用降到很小。我做了个简单的对比,用mplayer、迅雷看看还有我的播放器播放一个4G大小的视频,那两个播放器内存都要200多M,我的稳定在50多点,效果很明显啊!而且对播放流畅度神马的无影响。


    音频播放目前用的是portaudio。windows上没问题,linux上有点问题。不知道有没有其他的跨平台的库可以播放音频。

    播放器也刚刚开始做,目前功能还比较简单,就是能正常播放视频了。不能seek,不支持字幕。还有个bug,就是缩放窗口时经常崩溃,我也崩溃了,还没找到原因。

    废话了这么多,最后贴上项目网址:

    https://github.com/wang-bin/QtAV

下载编译好的文件:https://sourceforge.net/projects/qtav/

    欢迎大家共同学习交流音视频播放的问题,也欢迎参与写播放器



你可能感兴趣的:(C++,音视频,Qt)