iOS视频硬编码技术
一.iOS视频采集硬编码
基本原理
硬编码 & 软编码
硬编码:通过系统自带的Camera录制视频,实际上调用的是底层的高清编码硬件模块,即显卡,不使用CPU,速度快
软编码:使用CPU进行编码,如常见C/C // [videoOutput setAlwaysDiscardsLateVideoFrames:NO];
// 3.2 设置输出代理,捕获视频样品数据
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[videoOutput setSampleBufferDelegate:self queue:queue];
if ([captureSession canAddOutput:videoOutput]) {
[captureSession addOutput:videoOutput];
}
//3.3 设置视频输出方向
// 注意:设置方向,必须在videoOutput添加到captureSession之后,否则出错
AVCaptureConnection *connection = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
if (connection.isVideoOrientationSupported) {
[connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
}
- 添加视频预览层
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
self.preViewlayer = layer;
[layer setVideoGravity:AVLayerVideoGravityResizeAspect];
layer.frame = preview.bounds;
[preview.layer insertSublayer:layer atIndex:0];
5.开始采集
[captureSession startRunning];
• 获取摄像头方向
//指定摄像头方向,获取摄像头
-
(AVCaptureDevice *)getVideoDevice:(AVCaptureDevicePosition)position{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if (device.position == position) {
return device;
}
}
return nil;
}
• 切换摄像头
// 切换采集摄像头 -
(void)switchScene:(UIView *)preview{
// 1.添加动画
CATransition *rotaionAnim = [[CATransition alloc] init];
rotaionAnim.type = @“oglFlip”;
rotaionAnim.subtype = @“fromLeft”;
rotaionAnim.duration = 0.5;
[preview.layer addAnimation:rotaionAnim forKey:nil];// 2.获取当前镜头
AVCaptureDevicePosition position = self.videoDeviceInput.device.position == AVCaptureDevicePositionBack ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;// 3.创建新的input对象
AVCaptureDevice *newDevice = [self getVideoDevice:position];
AVCaptureDeviceInput *newDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:newDevice error:nil];// 4.移除旧输入,添加新输入
[self.captureSession beginConfiguration];
[self.captureSession removeInput:self.videoDeviceInput];
[self.captureSession addInput:newDeviceInput];
// 此处要重新设置视频输出方向,默认会旋转90度
self.connection = [_videoOutput connectionWithMediaType:AVMediaTypeVideo];
if (_connection.isVideoOrientationSupported) {
[_connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
}[self.captureSession commitConfiguration];
// 5.保存新输入
self.videoDeviceInput = newDeviceInput;
}
• 实现代理 – AVCaptureVideoDataOutputSampleBufferDelegat
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
NSLog(@“获取到一帧数据”);
// 对获取到的数据进行编码,编码部分在下一篇继续讲
dispatch_sync(mEncodeQueue, ^{
[self.encoder encodeFrame:sampleBuffer];
});
}
• 停止采集 - (void)stopCapturing{
// 停止扫描
[self.captureSession stopRunning];
// 移除预览图层
[self.preViewlayer remov