AVCapture iOS 系统相机知多少 - AVFoundation

几个枚举值

捕捉画面的质量的属性

我们可以通过设置AVCaptureSession的一些属性来改变捕捉画面的质量  
但是要注意:size相关的属性的时候需要首先进行测试设备是否支持
判断方法是  canSetSessionPreset 

AVCaptureSessionPresetPhoto ——适用于高分辨率照片质量输出

AVCaptureSessionPresetHigh ——适用于高质量视频和音频输出

AVCaptureSessionPresetMedium ——适用于中等质量输出,适合通过WiFi共享的输出视频和音频比特率

AVCaptureSessionPresetLow  ——适用于低质量输出,实现适合通过3G共享的输出视频和音频比特率

AVCaptureSessionPreset320x240 ——适用于320x240视频输出

AVCaptureSessionPreset352x288 ——适用于352x288视频输出

AVCaptureSessionPreset640x480 ——适用于640x480视频输出

AVCaptureSessionPreset960x540 ——适用于960x540视频输出

AVCaptureSessionPreset1280x720 ——适用于1280x720视频输出

AVCaptureSessionPreset1920x1080 ——适用于1920x1080视频输出

AVCaptureSessionPreset3840x2160 ——适用于3840x2160(UHD 4K)视频输出

AVCaptureSessionPresetiFrame960x540 ——可生成960x540 Apple iFrame视频和音频内容。以使用AAC音频以~30 Mbits / sec的速度实现960x540质量的iFrame H.264视频。 以iFrame格式捕获的QuickTime影片最适合编辑应用程序

AVCaptureSessionPresetiFrame1280x720 ——可生成1280x720 Apple iFrame视频和音频内容。以使用AAC音频以~40 Mbits / sec的速度实现1280x720质量的iFrame H.264视频。 以iFrame格式捕获的QuickTime影片最适合编辑应用程序

AVCaptureSessionPresetInputPriority ——指示会话输入的格式优先,此更改表明客户端选择的输入格式现在决定了输出端提供的服务质量等级。当客户端将会话预设设置为除AVCaptureSessionPresetInputPriority以外的任何其他内容时,会话将继续负责配置输入和输出,并可根据需要随意更改其输入的activeFormat

复制代码

设置摄像头的方向

typedef NS_ENUM(NSInteger, AVCaptureDevicePosition) {
 AVCaptureDevicePositionUnspecified         = 0,    // 最近打开的方向,记录最近时间打开的方向
 AVCaptureDevicePositionBack                = 1,    // 后置摄像头
 AVCaptureDevicePositionFront               = 2     // 前置摄像头
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;   
复制代码

设置闪光灯模式

typedef NS_ENUM(NSInteger, AVCaptureFlashMode) {
 AVCaptureFlashModeOff  = 0,    // 关闭闪光灯
 AVCaptureFlashModeOn   = 1,   // 打开闪光灯
 AVCaptureFlashModeAuto = 2   // 自动模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;
复制代码

手电筒模式

typedef NS_ENUM(NSInteger, AVCaptureTorchMode) {
 AVCaptureTorchModeOff  = 0,    // 手电筒关闭
 AVCaptureTorchModeOn   = 1,    // 手电筒打开
 AVCaptureTorchModeAuto = 2,   // 手电筒自动模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;
复制代码

系统对焦模式

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusSystem) {
AVCaptureAutoFocusSystemNone              = 0,      // 不设置对焦模式
AVCaptureAutoFocusSystemContrastDetection = 1,    //  对比度检测对焦
AVCaptureAutoFocusSystemPhaseDetection    = 2,       // 相位检测对焦
} NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
复制代码

视频防抖动模式

typedef NS_ENUM(NSInteger, AVCaptureVideoStabilizationMode) {
    AVCaptureVideoStabilizationModeOff       = 0,     // 视频防抖动模式关闭
    AVCaptureVideoStabilizationModeStandard  = 1,  // 视频防抖标准模式
    AVCaptureVideoStabilizationModeCinematic = 2,  // 视频防抖电影模式
    AVCaptureVideoStabilizationModeAuto      = -1,   // 视频防抖自动模式
} NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
复制代码

焦距调整

typedef NS_ENUM(NSInteger, AVCaptureFocusMode) {
 AVCaptureFocusModeLocked              = 0,     //  锁定对焦
 AVCaptureFocusModeAutoFocus           = 1,   //  自动对焦模式
 AVCaptureFocusModeContinuousAutoFocus = 2,  // 连续自动对焦
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;
复制代码

自动对焦范围限制

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusRangeRestriction) {
 AVCaptureAutoFocusRangeRestrictionNone = 0,    // 不限制
 AVCaptureAutoFocusRangeRestrictionNear = 1,     //  近距离对焦模式
 AVCaptureAutoFocusRangeRestrictionFar  = 2,      //   远距离对焦模式
} NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
复制代码

曝光模式设置

typedef NS_ENUM(NSInteger, AVCaptureExposureMode) {
 AVCaptureExposureModeLocked                            = 0,    // 锁定曝光
 AVCaptureExposureModeAutoExpose                        = 1,  // 自动曝光模式
 AVCaptureExposureModeContinuousAutoExposure            = 2,  //   连续自动曝光模式
 AVCaptureExposureModeCustom NS_ENUM_AVAILABLE_IOS(8_0) = 3,   // 自定义曝光模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;
复制代码

白平衡模式

typedef NS_ENUM(NSInteger, AVCaptureWhiteBalanceMode) {
 AVCaptureWhiteBalanceModeLocked            = 0,     // 锁定白平衡模式
 AVCaptureWhiteBalanceModeAutoWhiteBalance         = 1,  //   自动
    AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance = 2,  // 连续自动
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;
复制代码

授权状态 用户是否已经允许启用设备

typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
 AVAuthorizationStatusNotDetermined = 0,    //  授权状态未确定
 AVAuthorizationStatusRestricted,     //  授权受限
 AVAuthorizationStatusDenied,         //   授权被拒绝
 AVAuthorizationStatusAuthorized    //   授权被许可
} NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
复制代码

表示传输控件当前播放模式的枚举 - 播放控制模式

typedef NS_ENUM(NSInteger, AVCaptureDeviceTransportControlsPlaybackMode) {
 AVCaptureDeviceTransportControlsNotPlayingMode      = 0,
 AVCaptureDeviceTransportControlsPlayingMode         = 1
} NS_AVAILABLE(10_7, NA) __TVOS_PROHIBITED;
复制代码

几个对象

存在的几个对象的理解

  • AVCaptureDevice //硬件设备
  • AVCaptureInput //输入的设备
  • AVCaptureOutput //输出的数据
  • AVCaotureSession //协助input和output的数据传输

关系:
有很多Device的input和很多类型的Output,都通过一个CaptureSession来控制进行传输,即:CaputureDevice适配AVCaptureInput,通过Session来输入到AVCaptureOutput中,这样就达到了从设备到文件等持久传输的目的(如从相机设备采集图像到UIImage中)

那么如果视频输入(input)和对应的视频输出(output),音频对应音频,因而需要建立对应的Connections(连接),来各自连接它们,这个连接对象是由AVCaptureSession持有的,这个对象为 AVCaptureConnection,可以控制input和output的数据传输(通过各种的input port,都可以获取到相应的数据)

AVCaotureSession

self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession startRunning];
复制代码

需要创建一个session,发running消息,响应,就把输入设备的东西,提交到输出设备中。

如果想在一个已经使用session中(已经startRunning)更换新的device,删除旧的,方法

[session beginConfiguration];
[session commitConfiguration];
复制代码
//切换摄像头
- (BOOL)switchCameras {

    //判断是否有多个摄像头
    if (![self canSwitchCameras]){
        return NO;
    }
    
    //获取当前设备的反向设备
    NSError *error;
    AVCaptureDevice *videoDevice = [self inactiveCamera];//返回当前未激活的摄像头
    
    
    //将输入设备封装成AVCaptureDeviceInput
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    
    //判断videoInput 是否为nil
    if (videoInput)
    {
        //标注原配置变化开始
        [self.captureSession beginConfiguration];
        
        //将捕捉会话中,原本的捕捉输入设备移除
        [self.captureSession removeInput:self.activeVideoInput];
        
        //判断新的设备是否能加入
        if ([self.captureSession canAddInput:videoInput])
        {
            //能加入成功,则将videoInput 作为新的视频捕捉设备
            [self.captureSession addInput:videoInput];
            
            //将获得设备 改为 videoInput
            self.activeVideoInput = videoInput;
        }else
        {
            //如果新设备,无法加入。则将原本的视频捕捉设备重新加入到捕捉会话中
            [self.captureSession addInput:self.activeVideoInput];
        }
        
        //配置完成后, AVCaptureSession commitConfiguration 会分批的将所有变更整合在一起。
        [self.captureSession commitConfiguration];
    }else{
        return NO;
    }
    return YES;
}
复制代码

AVCaptureDevice

Device是对硬件的一对一的表示,一个AVCaptureDevice对象,对应一个实际的硬件设备\

/* 创建并配置输入设备 */
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if (device==nil) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" 
                   message:@"设备没有摄像头" 
                   preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"确认" 
        style:UIAlertActionStyleDefault 
        handler:^(UIAlertAction * _Nonnull action) {

        }]];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }
    // Device
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // Input
    _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    
    //Out put
    AVCaptureStillImageOutput *imageOutput; //图片的输出
    AVCaptureMovieFileOutput *movieOutput; //视频的输出
    
    self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];
    
    
复制代码

然后添加input到session的模式(检查是否可添加)

// Session 添加输入输出设备前要判断该手机(设备)能否添加输入输出设备。
    _session = [[AVCaptureSession alloc]init];
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    if ([_session canAddInput:self.input])
    {
        [_session addInput:self.input];
    }

    //if ([_session canAddOutput:self.output])
    //{
    //    [_session addOutput:self.output];
    //}
    if ([self.captureSession canAddOutput:self.movieOutput]){
        [self.captureSession addOutput:self.movieOutput];
    }

复制代码

AVCaptureOutput

Output的使用
ios中,分为MovieFile(输出成movie文件)、VideoData(适用各个Frame的处理)、AudioData(声音采集)、StillImage(静态图像拍照)几种output,它们都继承与AVCaptureOutput

AVCaptureDeviceInput

    self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
复制代码

猜你喜欢

转载自juejin.im/post/7018816531425394719