本文分为以下几个步骤:
*1.数据采集
*2.配置相关参数
*3.准备开始编码
*4.编码完成
*5.拼接H264文件
*6.写入文件
*7.停止捕捉
首先,给相关的类配置相关的对象:
*捕捉会话:AVCaptureSession
*捕捉设备输入:AVCaptureDeviceInput
*捕捉预览:AVCaptureVideoPreviewLayer
*捕捉设备输出:AVCaptureVideoDataOutput
*编码会话对象:VTCompressionSessionRef
第一步:数据采集
第二步:配置VideoToolbox的相关参数
/*
参数2、参数3:设置宽、高
参数4:设置编码类型
参数8:编码完成后的回到函数,
参数9:self,需要桥接当前的对象过去
参数10:指定的sEncodeingSession地址。
*/
1.创建VideoToolBox中的Session:VTCompressionSessionCreate();
2.设置相关属性配置:VTSessionSetProperty
3.开始编码:VTCompressionSessionPrepareToEncodeFrames
第三步:对采集到的数据进行编码,采集到的数据,经过协议协议方法中的CMSampleBufferRef封装着数据。这个协议方法,无论是采集到的是音频还是视频,都会回到这个函数,对音视频的编码,可以根据AVCaptureOutput 这个对象是AVCaptureAudioDataOutput 还是AVCaptureVideoDataOutput来判断是音频还是视频。
协议方法:-(void)captureOutput:(AVCaptureOutput*)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
第四步,对采集到的数据进行编码,先从CMSampleBufferRef中获取视频帧,获取相对应的帧时间frameID,然后构建编码函数。
参数类型:
参数1;encodesession
参数2;未编码的数据
参数3;时间戳
参数4;帧展示时间,如果没有时间信息,kCMTimeInvalid
参数5;帧属性 NULL
参数6;回调 编码过程回调 NULL
参数7;flags 同步还是异步
编码函数:VTCompressionSessionEncodeFrame()
第五步:编码完成之后,会进行一个回到函数,这个函数是自己自定义的,是使用C语言的方法来回调,函数涉及到的具体参数,可以通过创建sEncodeingSession时,点击相关的参数进去查看参考。在这个回调函数当中,分为以下几步:
回调函数:
voidDidCompressH264(void*outputCallbackRefCon,void*sourceFrameRefCon,OSStatusstatus,VTEncodeInfoFlagsinfoFlags,CMSampleBufferRefsamplebuffer)
1;判断返回的状态以及数据有没有准备好,没有则返回。
2:在C语言函数当中,获取当前的对象,将当前对象进行桥接。
3:判断是否为关键帧,如果是关键帧,就获取sps和pps,然后写入H264文件,获取sps和pps的时候,需要获取到相对应ppsSize,ppsContent以及ppsCount,sps同理。
4:获取NALU数据,在这个NALU获取数据时候,需要进行大小端切换,然后在写入H264文件。
第六步: 写入数据,将编码后获取到的sps和pps写入数据,以及将NALU数据写入数据,在将这些数据写入之前,要先写入他们的起始位0001。
第七步:完成捕捉。
使用的函数:VTCompressionSessionCompleteFrames()