本文介绍了一种采用Qt5.0的Multimedia多媒体技术实现音视频采集和本地播放,采用FFmepg开源库把所采集的原始视频数据进行编码成H.264压缩格式,采用G.711编码方式把所采集的原始音频数据编码,再把编码之后的音视频压缩数据进行网络传输的技术。
利用QT技术开发而成的即时通讯demo,可参考下载AnyChat 音视频SDK包中的源代码,anychatcoresdk_linux_x86_r4238\src\client\Qt5\helloAnyChat,更多相关技术可登陆技术论坛共同讨论bbs.anychat.cn
Qt是一个跨平台的C++图形用户界面应用程序框架,凭借其优良的跨平台特性、良好的封装机制、丰富的API、大量的开发文档等优点,得到了很多软件开发者的青睐。Qt的多媒体技术发展到现在,使用简单、功能灵活,已经支持跨平台开发,支持QML以获得更多资源,它为开发者提供了一系列丰富的接口,使开发者能够轻松便利的使用平台的、媒体回放以及操作摄像机和收音机设备的多媒体技术。
一、音视频编码
音视频编码技术就是采用特定的压缩技术,将某个音频或视频格式的文件转换成另一种音频或视频格式文件的方式。
视频的编码方式有很多,目前最为常用的是MPEG系列和H.26X系列。其中MPEG系列是由ISO所制定而发布的视频、音频、数据的压缩标准。H.26X系列是由国际电信联盟(ITU-T)开发的视频压缩编解码标准,包括H.261、H.262、H.263、H.263+、H.263++、H.264,其中H.264标准是由国际电信联盟电信标准化部门(ITU-T)和ISO/IEC共同研究发布。与MPEG相比,H.264具有更高的数据压缩比,在同等图像质量下,H.264的数据压缩率比MPEG-2高2倍~3倍,比MPEG-4提高了近30%。经过H.264压缩的视频数据,提高了存储性能,在网络传输过程中占用的宽带更少更经济,极大地抑制了由于摄像机噪声导致的图像失真,背景流动现象,使图像质量更加清晰。
G.711是由国际电信联盟(ITU-T)制定的音频编码方式,又称ITU-TG.711,目前有两种编码方式:A-law以及Mu-law,Mu-law主要运用于北美和日本,A-law主要用于欧洲和世界其他地区。
二、FFmpeg及X264编译
FFmpeg是一款免费的开源的,能够跨平台调用的软件,可以用来记录、转换数字音视频,并能将数字音视频转化为流。除了包含目前领先的音/视频编码库libavcodec之外,还包括了以下几个部分:
libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能。
libavutil:包含一些公共的工具函数,是ffmpeg的基础。
libswscale:图像格式转换、视频场景比例缩放、色彩映射转换。
libpostproc:图像后期效果处理。
FFmpeg是基于Linux平台开发的,要想在windows平台下使用,可以采用MingGW编译FFmpeg源码,生成动态库文件。但是下载的FFMpeg源码默认是不包含H.264编解码功能的,需要额外下载x264源码,采用MingGW编译器把x264编译成动态库之后,在编译FFMpeg的时候把H.264编解码功能添加进去,才能在FFmpeg中成功添加H.264编解码功能。
三、基于Qt多媒体技术的音视频采集和编码实现
1.多媒体模块的导入
Qt5.0版本中的多媒体模块提供了一组丰富的QML类型和C++类以满足多媒体开发的需要,另外还提供了必要的API接口来访问照相机和收音机设备。
要在Qt5.0以上的版本中使用多媒体模块,首先应该在工程中进行如下的设置:
CONFIG+=mobility MOBILITY=multimedia 这样设置之后才能使用Qt的多媒体库。
2.FFMpeg头文件及动态库的添加
把编译好的FFmpegSDK文件放到一个文件夹内,首先在工程中设置好头文件路径以及需要的库文件,在工程中的文件内包含使用的头文件,注意的是,因为FFMepg库的接口都是C函数,头文件中也没有extern“C”的声明,而Qt是C++环境,所以在使用头文件时,需要添加extern“C”。
3.摄像机视频的采集和编码
Qt中的QCamera类为系统的摄像机设备提供了接口,它和QVideoWidget搭配使用用来显示摄像机视频图像,搭配QMediaRecoder可以保存摄像机视频,搭配QCameraimageCapture可以抓拍摄像机图像。 本文所介绍的视频采集方法,除了需要实时显示摄像机图像之外,还需要同步获取摄像机视频源数据,所以引入了QAbstractVideoSurface这个类。在工程中添加类VideoWidgetSurface,该类继承基类
QAbstractVideoSurface:
(1)重载虚基函数QList<QVideoFrame::PixelFormat>supportedPixelFormats(QAbstractVideoBuffer::HandleTypehandleType=QAbstractVideoBuffer::NoHandle)const;用于设置程序支持的原始视频格式;
(2)重载基类的boolpresent(constQVideoFrame&frame)函数,用于获取当前帧的视频源数据;
(3)重载基类的boolstart(constQVideoSurfaceFormat&format)函数,用于启动视频表面及进行相应的窗口设置;
(4)重载基类的voidstop()函数,用于停止当前的视频表面和释放调用start时所产生的资源。
(5)添加voidpaint(QPainter*painter)函数,用以绘制视频图像,以在本地窗口中输出。其次,新建一个QCamera对象m_pCamera,新建一个VideoWidgetSurface对象m_pVideoSurface;通过m_pCamera->service()->requestControl<QVideoRendererControl*>()方法获取QVideoRendererControl的指针pControl,如果该指针存在,则调用pControl的setSurface关联到m_pVideoSurface。这样当m_pCamera执行完Start()后,就可以在m_pVideoSuface对象的present函数中得到每一帧的QVideoFrame视频数据。在测试程序中获取的视频数据格式为RGB32,需要先转为YUV240P的格式,然后再用FFmpeg的H.264编码功能实现视频数据编码。
4.麦克风音频的采集和编码
Qt中的QAudioInput类可以进行本地的麦克风、收音机等设备的音频采集,而QAudioOutput类可以实现把本地的音频数据输出到音频输出设备,实现音频的播放功能。具体的步骤如下:
(1)获取声音的输入输出设备,可以直接获取默认的设备,也可以在程序中查找声音输入输出设备,然后指定,本文采用直接获取默认设备的方式,调用QAudioDeviceInfo::defaultInputDevice()方法得到QAudioDeviceInfo的指针m_audioInputDevice;调用QAudioDeviceInfo::defaultOutputDevice()方法得到QAudioDeviceInfo的指针m_audioOutputDevice。
(2)设置QAudioFormat格式,QAudioInput和QAudioOutput对象的QAudioFormat格式应一致,否则播放的声音就与输入的声音不同。新建一个QAudioFormat对象format,
本例中设置如下:采样率(SampleRate):8000;信道数(ChannelCount):1;样本大小(SampleSize):16;编码方式(Codec):"audio/pcm";字节序(ByteOrder):QAudioFormat::LittleEndian;采样类型(SampleType):QAudioFormat::SignedInt。
(3)分别按照上述的声音输入输出设备和声音参数信息创建QAudioInput对象m_audioInput和QaudioOutput对象m_audioOutput。
(4)调用m_audioInput和m_audioOutput的start接口,打开声音输入输出设备,将分别返回QIODevice指针m_audioInputIODevice和m_audioOutputIODevice。
(5)当声音输入设备采集到声音数据后,将触发m_audioInputIODevice的readyRead()信号,所以将此信号与该类的captureDataFromDevice()函数连接,即可在此函数内处理得到的原始数据。
(6)在captureDataFromDevice()槽函数中调用m_audioInputIODevice的read函数得到原始的音频数据。
(7)声音播放:把得到的原始音频数据写入缓存,然后调用m_audioOutputIODevice的write函数把缓存内的数据写入声音输出设备即可听到声音。
(8)原始音频数据采用G.711编码方式进行编码,就可以获得压缩后的音频数据,即可进行网络传输。
四、开发过程中注意事项
1.要在本地计算机设备中显示摄像机视频,在显示的窗口类重载paintEvent函数,在该函数内调用VideoWidgetSurface的paint函数.
2.FFmpeg的初始化只需要一次,不能在每次进行编码时都初始化和重新设置H.264编码器。
五、结语
本文基于Windows操作系统,Qt5.1开发平台,充分利用Qt的多媒体模块和FFmpeg及G.711的编码技术,实现了本地摄像头、麦克风等设备的音视频采集和编码功能,不仅能够在本地实现音视频的预览,而且为实现音视频的网络传输做好了充分的准备。本例在win7操作系统中测试通过,同样也可应用于ipad等移动设备。
参考文献:
[1]http://qt-project.org/doc/qt-5.0/qtmultimedia/qtmultimedia-index.html
[2]黄诗文.基于ffmpeg的高性能高清流媒体播放器软件设计[D].浙江:浙江大学[硕士论文],2012
[3]司马飞,善学文,倪宏.Windows平台下应用FFMPEG实现H.264视频回放:[J].微计算机应,2008,29(11):61-65
[4]张国庆.基于FFmpeg的视频转码与保护系统的设计与实现[D].湖北:华中师范大学[说是论文],2011
本篇文章来源于中国安防杂志网(www.cspmag.cn)