1、前言
VideoToolbox
是 Apple
在 iOS 8
之后推出的用于视频硬编码、解码的工具库。 平时所说的软编解码是指使用 ffmpeg
这个第三方库去做编码解码。
2、原始裸流 CMSampleBuffer 获取
一般在做音视频应用开发的时候,我们都是用 AVFoundation
去做原始数据采集的,使用前置摄像头或者后置摄像头采集视频数据,使用麦克风采集音频数据。
在 AVCaptureVideoDataOutputSampleBufferDelegate
这个代理的
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
回调方法里面可以获取采集的视频裸流信息。注意AVCaptureAudioDataOutputSampleBufferDelegate
音频输出的代理方法也是这个,那么我们如何区分到底是音频数据还是视频数据呢?这里有两种方案:
-
判断
output
是AVCaptureAudioDataOutput
(音频) 还是AVCaptureVideoDataOutput
(视频) -
判断
connection
是audioConnection
(音频) 还是videoConnection
(视频), 我自己在代码里使用属性声明了audioConnection
和videoConnection
。
3、 H.264 硬编码
3.1 初始化编码会话
-
创建编码会话
创建编码会话的时候注意传入了我们的编码回调函数
VideoEncodeCallback
,这个函数会多次调用。//创建编码会话 OSStatus status = VTCompressionSessionCreate(kCFAllocatorDefault, (int32_t)_config.width, (int32_t)_config.height, kCMVideoCodecType_H264, NULL, NULL, NULL, VideoEncodeCallback, (__bridge void * _Nullable)(self), &_encodeSession); if (status != noErr) { NSLog(@"VTCompressionSession create failed. status=%d", (int)status); return self; } else { NSLog(@"VTCompressionSession create success"); }
-
设置编码会话属性
//设置实时编码 VTSessionSetProperty(_encodeSession, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue); //指定编码比特流的配置文件和级别。直播一般使用baseline,可减少由于b帧带来的延时 VTSessionSetProperty(_encodeSession, kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_Baseline_AutoLevel); //设置码率均值(比特率可以高于此。默认比特率为零,表示视频编码器。应该确定压缩数据的大小。注意,比特率设置只在定时时有效) CFNumberRef bit = (__bridge CFNumberRef)@(_config.bitrate); VTSessionSetProperty(_encodeSession, kVTCompressionPropertyKey_AverageBitRate, bit); //设置码率上限 CFArrayRef limits = (__bridge C