采集音频和摄像头视频并实时h264编码及aac编码

DoubleLi DoubleLi     2022-09-14     748

关键词:

0. 前言

  我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法。那种方法有一些局限性,不适合实时性质的应用,如:视频会议、视频聊天、视频监控等。本文所使用的技术,适用于这种实时性的应用,通过处理采集出来的音视频的每一帧,实现实时编码,实时输出。这是我做直播系列应用的一部分,目前的情况是输入端采用DirectShow技术捕获音视频,然后对视频进行h.264编码,对音频进行aac编码,输出端则是生成文件,接下来还要进一步扩展输入端和输出端,以支持文件、桌面输入,RTSP、RTMP、HTTP等流式协议输出。

 

1. 简单介绍

  首先是捕获,这里采用了DirectShow的方式,对它进行了一定程度的封装,包括音视频。好处是直接使用native api,你可以做想做的任何修改,坏处是,不能跨平台,采集音视频这种应用,linux平台也是需要滴呀。有跨平台的做法,对视频,可以使用OpenCV,对音频,可以使用OpenAL或PortAudio等,这样就行了。

  编码可以选择的余地比较大,对视频来讲,有H264, MPEG-4, WebM/VP8, Theora等,音频有Speex, AAC, Ogg/Vorbis等,它们都有相应的开源项目方案,我采用的是x264进行H264编码,libfaac进行aac编码,之后是否更改编码方案,等具体项目需求再说了。这里提一下WebM,Google牵头的项目,完全开放和自由,使用VP8和Vorbis编码,webm(mkv)封装,有多家巨头支持,目的是想要取代当前的H264视频编码,号称比后者更加优秀,我没有测试过实际效果。不过有商业公司牵头就是不一样,各项支持都很全面,有时间了关注一下。

 

2. 逻辑和流程

  基本的思想是实现dshow ISampleGrabberCB接口,通过回调来保存每一个buffer。除了界面线程和dshow自己的线程之外,我们启动了两个线程,AudioEncoderThread和VideoEncoderThread,分别从SampleGrabber中取出数据,调用编码器进行编码,编码后的文件可以直接输出。看图:

     

  程序是用VS2010构建的,看张工程截图:

      

  Base下面的是对系统API的一些简单封装,主要是线程和锁。我这里简单也封装的了一下dshow的捕获过程,包括graph builder的创建,filter的连接等。directshow是出了名的难用,没办法,难用也得用。因为是VS2010,调用的Windows SDK 7.1中的dshow,没有qedit.h这个文件,而它正式定义ISampleGrabberCB的。不急,系统中还是有qedit.dll的,我们要做的就是从Windows SDK 6.0中,把它拷过来,然后在stdafx.h中加入这几行代码,就可以了

1 #pragma include_alias( "dxtrans.h", "qedit.h" )
2 #define __IDxtCompositor_INTERFACE_DEFINED__
3 #define __IDxtAlphaSetter_INTERFACE_DEFINED__
4 #define __IDxtJpeg_INTERFACE_DEFINED__
5 #define __IDxtKey_INTERFACE_DEFINED__
6 #include "qedit.h"

 

3. 音视频编码

  相关文件:

      

  Encoder下就是音视频编码相关的代码。X264Encoder封装了调用x264编码器的操作,FAACEncoder封装了调用libfaac编码器的操作,VideoEncoderThread和AudioEncoderThread负责主要的流程。下面我把关键代码贴出来,大家可以参考一下。

  A. 视频编码线程

  主要流程是首先初始化x264编码器,然后开始循环调用DSVideoGraph,从SampleGrabber中取出视频帧,调用x264进行编码,流程比较简单,调用的频率就是你想要获取的视频帧率。要注意的一点是,x264进行编码比较耗时,在计算线程Sleep时间时,要把这个过程消耗的时间算上,以免采集的视频帧率错误。

  B. 音频编码线程

  主要流程和视频编码线程相同,也是初始化FAAC编码器,然后循环调用DSAudioGraph,从SampleGrabber中取出视频帧,调用faac进行编码。和视频不同的是,音频的sample的频率是非常快的,所以几乎要不断的进行采集,但前提是SampleGrabber中捕获到新数据了才行,不然你的程序cpu就100%了,下面代码中IsBufferAvailaber()就是做这个检测的。

  调用faac进行编码的时候,有点需要注意,大家特别注意下,不然编码出来的音频会很不正常,搞不好的话会很头疼的。先看下faac.h的相关接口

1 faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, unsigned int numChannels,
2 unsigned long *inputSamples, unsigned long *maxOutputBytes);
3
4 int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput,
5 unsigned char *outputBuffer, unsigned int bufferSize);

  faacEncEncode第三个参数指的是传入的sample的个数,这个值要和调用faacEncOpen返回的inputSamples相等。要做到这点,就要在dshow中设置好buffsize,公式是:

BufferSize = aac_frame_len * channels * wBytesPerSample
// aac_frame_len = 1024

 

4. 程序界面

  运行中

     

  捕获完成后生成aac 和 264文件

     

  生成的aac文件用MediaInfo读出来的编码格式

     

  生成的264文件用MediaInfo读出来的编码格式

     

  用mp4box封装一下,把264和aac存放到mp4容器文件中,就可以在播放器中播放了

     

 

使用 ffmpeg 实时解码 android 的硬件编码 H264 摄像头馈送

】使用ffmpeg实时解码android的硬件编码H264摄像头馈送【英文标题】:Decodeandroid\'shardwareencodedH264camerafeedusingffmpeginrealtime【发布时间】:2011-12-0608:48:22【问题描述】:我正在尝试使用Android上的硬件H264编码器从摄像头创建视频,并... 查看详情

android制作一个视频录制器(代码片段)

...介用户打开页面时,我们打开相机预览,摄像机采集到的数据通过SurfaceView来展示给用户。用户点击开始录制,我们通过Camera2的Api向相机服务发送录制Request,录制的数据关联在我们传给相机的Surface中。这里录制数据的... 查看详情

aac音频编码相关的原理和设置

参考技术AAAC(AdvancedAudioCoding),中文名:高级音频编码,出现于1997年,基于MPEG-2的音频编码技术。由FraunhoferIIS、杜比实验室、AT&T、Sony等公司共同开发,目的是取代MP3格式。2000年,MPEG-4标准出现后,AAC重新集成了其特性,加... 查看详情

直播技术原理讲解

视频直播流程视频直播的流程可以分为如下几步: 采集—>处理—>编码和封装—>推流到服务器—>服务器流分发—>播放器流播放1.采集采集是整个视频推流过程中的第一个环节,它从系统的采集设备... 查看详情

视频直播技术:实时视频编码之h264硬编码

...用java调用so库。2.硬编码过程和原理过程:通过MediaRecoder采集视频,再将视频 查看详情

串流直播流媒体视频发布平台功能模块和产品技术参数

...国产化软件,具有完全自主知识产权;2、支持USB摄像头、视频采集卡、虚拟摄像头等多种信号源,支持视频采集分辨率和帧率设置,支持对采集的视频去交错处理;3、支持音频信号采集、采样率设置、声道设... 查看详情

直播流程,视频推流,视频拉流,简介,smtprtmphlsplplayerkit

...aitongtong/p/11248966.html 1、音视频处理的一般流程:数据采集→数据编码→数据传输(流媒体服务器)→解码数据→播放显示1、数据采集:摄像机及拾音器收集视频及音频数据,此时得到的为原始数据涉及技术或协议:摄... 查看详情

android直播调研

...:Camera。Android要做机型适配工作手机直播SDK通过手机摄像头和麦克风直接采集视频数据和音频数据。其中,视频采样数据一般采用RGB或YUV格式、音频采样数据一般采用PCM格式。对于采集到的原始音视频的体积是非常大的,... 查看详情

rtsp实时音视频(h264/h265/aac)开发实战项目

...57课程博客:2、windows平台RTSPServer实现1、directShow采集摄像头数据课程视频:https://edu.csdn.net 查看详情

如何把摄像头采集的rgb图像转成yuv格式,并进行h264硬编码?

如何把摄像头采集的rgb图像转成yuv格式,并进行H264硬编码?wince开发环境请附源码,高分悬赏!!!找北京的盟石科技公司,他们能做。或者找一个FPGA,写VHDL....省略一百万行文字......然后,PXA610进行硬件编码,然后.....源代码... 查看详情

使用 Live555 从连接到 H264 编码器的 IP 摄像机流式传输实时视频

】使用Live555从连接到H264编码器的IP摄像机流式传输实时视频【英文标题】:UsingLive555toStreamLiveVideofromanIPcameraconnectedtoanH264encoder【发布时间】:2015-02-0110:55:29【问题描述】:我正在使用基于德州仪器OMAP-L138的定制板,该板基本上... 查看详情

live555移植到hi3516做rtsp服务器

...端播放服务器上上面格式文件外,另添加了实时播放hi3516摄像头图像与音频的功能。live555源码目录如下:四个基本的库分别是:BasicUsageEnvironment,groupsock,liveMedia和UsageEnvironment。编译后即生成这4个库文件:这里我只简单说下liveMedia库... 查看详情

嵌入式视频编码(h264)hi3518

...主要是API,以备不时之用       摄像头获取的模拟信号通过经芯片处理(我们使用的是CX25825),将模拟信号转成数字信号,产生标准的ITU656YUV格式的数字信号以帧为单位送到编码卡上的DSP和内存中。分... 查看详情

研究android音视频-3-在android设备上采集音视频并使用mediacodec编码为h.264(代码片段)

...文解决的问题本文主要使用MediaCodec硬编码器对Android设备采集的音视频编码封装音视频基础编码器封装音频编码器封装视频编码器使用新封装的视频编码器改造示例2使用Camera进行视频录制(YUV420SP)并保存为视频流(H.264)使用AudioRecor... 查看详情

转音视频封装格式编码格式知识

...件其实只能算是一种封装标准。一个完整的视频文件是由音频和视频2部分组成的。H264、Xvid等就是视频编码格式,MP3、AAC等就是音频编码格式。例如:将一个Xvid视频编码文件和一个MP3音频编码文件按AVI封装标准封装以后,就得... 查看详情

网易云紧跟直播步伐,look直播全面上线

...时必须进行解码。二、直播系统音视频的采集:通过调用摄像头、麦克风直接采集音视频数 查看详情

视音频编解码基本术语及解释

摘要:      整理了一些基本视音频术语,用于入门和查询使用。H264:H264是视频的标准,是MPEG4-10,基于内容的高效编码方式.H.264/MPEG-4第10部分,或称AVC(AdvancedVideoCoding,高级视频编码),是一种视频压缩标... 查看详情

ffmpeg代码实现流媒体推流(rtsp)

...YUV,接着把YUV编码成H264,再把H264码流推到RTSP服务器;把采集到的PCM编码为AAC,再把AAC推流至RTSP服务器。看了雷神的一篇文章:最简单的基于FFmpeg的推流器(以推送RTMP为例),他是把本地的视频文件推流至RTMP服务器,并不符合... 查看详情