AVCaptureDevice.
系统通过AVCaptureDevice来得到和管理设备的输入捕获设备,比如camara和麦克风,对于手机来说有2个carama(前后)和一个麦克风。
如果要设置某个设备的属性,那么在设置之前必须要调用
(BOOL)lockForConfiguration:(NSError**)outError;
来进行锁定,然后进行属性设置,设置后调用
(void)unlockForConfiguration;
来取消锁定,这样做的目的是保证某个时间只有一个设备来进行属性设置。
对于carama设备里面支持一个手电筒的功能。
//是否有手电筒
@property(nonatomic,readonly)BOOLhasTorch;
//手电筒是否有效,如果过热时系统会无效。
@property(nonatomic,readonly,getter=isTorchAvailable)BOOLtorchAvailable NS_AVAILABLE_IOS(5_0);
//手电筒是否是亮的
@property(nonatomic,readonly,getter=isTorchActive)BOOLtorchActive NS_AVAILABLE_IOS(6_0);
//手电筒亮的级别,从0-1
@property(nonatomic,readonly)floattorchLevel NS_AVAILABLE_IOS(5_0);
//是否支持某种模式。
-(BOOL)isTorchModeSupported:(AVCaptureTorchMode)torchMode;
//设置模式是开电筒还是关还是自动。
@property(nonatomic)AVCaptureTorchModetorchMode;
//设置电筒开时的亮度级别,如果系统过热时可能会失败。
-(BOOL)setTorchModeOnWithLevel:(float)torchLevelerror:(NSError **)outError NS_AVAILABLE_IOS(6_0);
对于carama还有其他的属性,比如闪光等,焦距,白平衡,底亮度增强等的设置。还支持捕捉的设备的移动通知,一旦通过
@property(nonatomic,getter=isSubjectAreaChangeMonitoringEnabled)BOOLsubjectAreaChangeMonitoringEnabled NS_AVAILABLE_IOS(5_0);
设置可以监控是否移动,一旦有移动则会接收到AVCaptureDeviceSubjectAreaDidChangeNotification的通知。
一次会话用来建立输出和输入的连接AVCaptureSession。一个会话可以有多个输入和多个输出,输出和输入之间通过AVCaptureConnection来建立连接。一个AVCaptureConnection用来描述多个AVCaptureInputPort和一个AVCaptureOutput或者AVCaptureVideoPreviewLayer的关联(注意一个AVCaptureOutput可以有多个AVCaptureConnection),也就是说AVCaptureConneciton可以不关联输出。在IOS中用户不能建立AVCaptureConnection来关联输入和输出,而是系统内部来建立的Connection.而是用户直接调用Session的AddInput,AddOutput来指定输入和输出。
为什么要对AVCaptueInput做抽象,个人认为是因为输入不仅仅是设备还有可能是屏幕也算是一种输入,所以这里建立一个输入的抽象类,而具体的派生类则有AVCaptureDeviceInput代表设备输入源,而AVCaptureScreenInput则是代表屏幕输入源,对于设备输入源来说他的建立是通过AVCaptureDevice来建立的。而为什么要有AVCaptureInputPort则是因为AVCaptureInput描述一个整体的输入源,比如carama,而其实carama既能接收视频也能接收音频数据,所以有两个输入AVCaptureInputPort。
AVCaptureSession类。
//AVCaptureInput集合
@property(nonatomic,readonly) NSArray*inputs
//添加输入
(void)addInput:(AVCaptureInput*)input
//判断是否能添加输入
-(BOOL)canAddInput:(AVCaptureInput*)input
//添加输出,可以没有输出。这个函数内部估计在调用addOutput时内部会建立AVCaptureConnection来跟input建立关联。
(void)addOutput:(AVCaptureOutput*)output
//是否能添加输出。
(BOOL)canAddOutput:(AVCaptureOutput*)output
(void)removeInput:(AVCaptureInput*)input
(void)removeOutput:(AVCaptureOutput*)output
//是否当前被终止捕获,可以通过KVO来监控这个属性。
@property(nonatomic,readonly, getter=isInterrupted) BOOL interrupted
//AVCaptureOutput的集合,这个可以是空如果是使用预览Layer的话。
@property(nonatomic,readonly) NSArray*outputs
//判断当前是否在运行,KVO
@property(nonatomic,readonly, getter=isRunning) BOOL running
//开始和结束会话
(void)startRunning
-(void)stopRunning
//进行会话的预设,比如捕获视屏的尺寸啊,质量等等。
@property(nonatomic,copy) NSString*sessionPreset
//判断是否某个属性能够设置。
(BOOL)canSetSessionPreset:(NSString*)preset
//开始配置和结束配置,比如添加输入输出,设置预设值,都在这个之间设置会提升性能以及保持原子性。
(void)beginConfiguration
-(void)commitConfiguration
AVCaptureConnection
这个类是用来连接输入和输出的,在IOS中不能建立,只能设置其中的属性,而这个实例是从AVCaptureVideoPreviewLayer或者AVCaptureOutput中获得,
//??
@property(nonatomic,getter=isEnabled) BOOL enabled
//??
@property(nonatomic,readonly, getter=isActive) BOOL active
//输入的端口数组
@property(nonatomic,readonly) NSArray*inputPorts
//输出
@property(nonatomic,readonly) AVCaptureOutput*output
//预览层
@property (nonatomic,readonly) AVCaptureVideoPreviewLayer *videoPreviewLayer
//下面是设置视频的方向,捕获的帧的间隔时间
videoOrientation property
supportsVideoOrientation property
videoMinFrameDuration property
supportsVideoMinFrameDuration property
videoMaxFrameDuration property
supportsVideoMaxFrameDuration property
videoScaleAndCropFactor property
videoMaxScaleAndCropFactor property
AVCaptureInput。
//得到所有输入端口
@property(nonatomic,readonly)NSArray*ports;
输入现在有AVCaptureDeviceInput和AVCaptureScreenInput。具体参考类的实现。
AVCaptureInputPort是具体的端口类。方法参考类的定义。
AVCaptureOutput一共有如下派生类的输出:
//音频数据输出
AVCaptureAudioDataOutput
AVCaptureFileOutput,AVCaptureMovieFileOutput文件以及电影文件的输出后者是派生类
AVCaptureStillImageOutput//图片输出
//可以设置输出的图片的属性,这些属性只是下面可以支持的类型中设置。
@property(nonatomic,copy) NSDictionary*outputSettings;
@property(nonatomic,readonly)NSArray*availableImageDataCVPixelFormatTypes;
@property(nonatomic,readonly)NSArray*availableImageDataCodecTypes;
//执行拍照功能,注意block可能不是运行在主线程中。
(void)captureStillImageAsynchronouslyFromConnection:(AVCaptureConnection*)connection completionHandler:(void(^)(CMSampleBufferRefimageDataSampleBuffer, NSError*error))handler;
(NSData*)jpegStillImageNSDataRepresentation:(CMSampleBufferRef)jpegSampleBuffer;
//视频数据输出。
AVCaptureVideoDataOutput
这个类通过一个委托来实现采集数据
(void)setSampleBufferDelegate:(id<AVCaptureVideoDataOutputSampleBufferDelegate>)sampleBufferDelegatequeue:(dispatch_queue_t)sampleBufferCallbackQueue;
一副图像数据根据不同的色彩模型可以不同编码。比如RGBA,YCbCr,YUV等。也就是说每一个像素可以通过不同的色彩模型表示,这里需要介绍面的概念,所谓面是存储这些像素点时是将各色彩模型中的分量分别存储还是统一存储。如果是统一存储则只有1面,而分别单独的存储则称为有多面。
(void)captureOutput:(AVCaptureOutput*)captureOutputdidOutputSampleBuffer:(CMSampleBufferRef)sampleBufferfromConnection:(AVCaptureConnection*)connection;
协议的回调函数CMSampleBufferRef制定监控的视频帧的样本采集缓存数据。
其中可以通过函数
CVImageBufferRefimageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);来得到其中的图片采集部分,CVImageBufferRef是专门用于保存视频的图片帧缓存的数据结构。这个数据结构有可能是描述OPENGL的帧信息也可能是描述像素表示的帧信息,如果是像素表示的帧信息则是一个
typedefCVImageBufferRef CVPixelBufferRef;
至于如何描述一个像素的色彩信息就可以参考上面所使用的颜色模型。