一、概述
从iOS4开始,AVFoundation框架增加了几个类,AVCaptureDevice、AVCaptureSession等,可以获取摄像头的数据,而不会弹出类似于ImagePicker一样的界面,我们可以将数据转为一张张的图片,然后我们可以即时显示在视图上,也可以使用FFMPEG或者其它的视频编码工具,来合成视频。
二、步骤
第一步:创建AVCaptureSession,添加输入,输出源
#import <AVFoundation/AVFoundation.h>
//创建并配置一个摄像会话,并启动。
- (void)setupCaptureSession
{
NSError *error = nil;
//创建会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
//设置视频质量
session.sessionPreset = AVCaptureSessionPresetMedium;
//获取合适的AVCaptureDevice
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建设备输入流,并增加到会话。
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input) {
//处理错误
}
[session addInput:input];
//创建一个视频输出流,并增加到会话。
AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput:output];
//配置输出流
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
//指定像素格式。
output.videoSettings = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
//设置FPS
output.minFrameDuration = CMTimeMake(1, 15);
//启动会话
[session startRunning];
//将会话与当前控制器关联
[self setSession:session];
}
第二步:实现AVCaptureVideoDataOutputSampleBufferDelegate协议方法
//当采样数据被写入缓冲区时调用
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
//抽取采样数据,合成UIImage对象
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
//后续自定义处理
xxxxxxxx
}
//抽取采样数据,合成UIImage对象
- (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
//锁定像素缓冲区的起始地址
CVPixelBufferLockBaseAddress(imageBuffer,0);
//获取每行像素的字节数
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
//获取像素缓冲区的宽度和高度
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
//创建基于设备的RGB颜色空间
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (!colorSpace)
{
NSLog(@"CGColorSpaceCreateDeviceRGB failure");
return nil;
}
//获取像素缓冲区的起始地址
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
//获取像素缓冲区的数据大小
size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
//使用提供的数据创建CGDataProviderRef
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize,NULL);
//通过CGDataProviderRef,创建CGImageRef
CGImageRef cgImage =
CGImageCreate(width,
height,
8,
32,
bytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
provider,
NULL,
true,
kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
//创建UIImage
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
//解锁像素缓冲区起始地址
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
return image;
}