iOS AVCaptureDevice 相机与镜头

2,961 阅读2分钟

截屏2021-12-09 下午3.42.07.png

AVCaptureDevice 一种为捕获会话提供输入(例如音频或视频)并提供针对特定于硬件的捕获功能的控件的设备。是关于硬件的接口,用于配置底层硬件的属性(如对焦,闪光灯,曝光等)。这些底层硬件包括前置摄像头、后置摄像头、麦克风、闪光灯等。
使用AVCaptureDeviceAVCaptureSession对象提供输入数据(如音频或视频)。

使用 AVCaptureDeviceDiscoverySession 获取AVCaptureDevice

public convenience init(deviceTypes: [AVCaptureDevice.DeviceType], mediaType: AVMediaType?, position: AVCaptureDevice.Position)

//通过这个参数获取可用device
var devices: [AVCaptureDevice]]
extension AVCaptureDevice.DeviceType {
    @available(iOS 10.0, *)
    public static let builtInMicrophone: AVCaptureDevice.DeviceType
    
    @available(iOS 10.0, *)
    public static let builtInWideAngleCamera: AVCaptureDevice.DeviceType

    @available(iOS 10.0, *)
    public static let builtInTelephotoCamera: AVCaptureDevice.DeviceType

    @available(iOS 13.0, *)
    public static let builtInUltraWideCamera: AVCaptureDevice.DeviceType

    @available(iOS 10.2, *)
    public static let builtInDualCamera: AVCaptureDevice.DeviceType

    @available(iOS 13.0, *)
    public static let builtInDualWideCamera: AVCaptureDevice.DeviceType

    @available(iOS 13.0, *)
    public static let builtInTripleCamera: AVCaptureDevice.DeviceType
    
    @available(iOS 11.1, *)
    public static let builtInTrueDepthCamera: AVCaptureDevice.DeviceType

    @available(iOS, introduced: 10.0, deprecated: 10.2, message: "Use AVCaptureDeviceTypeBuiltInDualCamera instead.")
    public static let builtInDuoCamera: AVCaptureDevice.DeviceType
}

@available(iOS  4.0, *)
 public enum Position : Int {
   case unspecified = 0
   case back = 1
   case front = 2
 }

AVCaptureDevice.DeviceType 枚举

枚举名称解释
builtInMicrophone内置麦克风。 (麦克风)
builtInWideAngleCamera内置广角相机。 (广角)
builtInTelephotoCamera内置摄像头设备的焦距比广角摄像头更长。(长焦)
builtInUltraWideCamera内置相机的焦距比广角相机的焦距短。(超广角)
builtInDualCamera广角相机和远摄相机的组合 (双摄 广角(远摄))
builtInDualWideCamera一种设备,包括两个固定焦距的相机,(一个超广角+一个广角)
builtInTripleCamera一种设备,该设备由三个固定焦距的相机,(超广角+广角+长焦)
builtInTrueDepthCamera相机和其他传感器的组合,可创建能够进行照片,视频和深度捕捉的捕捉设备。
builtInDuoCameraiOS 10.2 之后不推荐使用
枚举名称解释
unspecified未指定
back后置摄像头
front前置摄像头

如何使用

相机初始化 (AVCaptureDeviceInput)

   AVCaptureDevice *videoDevice;

    if (videoDevice == nil) {
        NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
           for (AVCaptureDevice *device in devices)
           {
              if ([device position] == cameraPosition)
              {
                  videoDevice = device;
              }
           }
        _isWideCamera = NO;
    }
    _inputCamera = videoDevice;
    
    
    if (!_inputCamera) {
        return nil;
    }
    
 
    // Create the capture session
    _captureSession = [[AVCaptureSession alloc] init];
    
    [_captureSession beginConfiguration];
    
    // Add the video input
    NSError *error = nil;
    videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_inputCamera error:&error];
    if ([_captureSession canAddInput:videoInput])
    {
        [_captureSession addInput:videoInput];
    }

切换摄像头 type -> BuiltInTripleCamera

BOOL isRunning = self.captureSession.isRunning;

    

    if (isRunning)  [self.captureSession stopRunning];

   

    BOOL isUpdateImageOrientation = curDevicePosition != _inputCamera.position;

    AVCaptureDevice *videoDevice;
    

    if ( @available (iOS 13.0, *)) {
    ///前提是 支持这个模式 
    // 切三摄全开模式
        videoDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInTripleCamera mediaType:AVMediaTypeVideo position:curDevicePosition];

    }
    

    [_captureSession beginConfiguration];

    _inputCamera = videoDevice;

    NSError *error;

    AVCaptureDeviceInput * newvideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_inputCamera error:&error];

    if (newvideoInput != nil {

        [_captureSession removeInput:videoInput];

        if ([_captureSession canAddInput:newvideoInput]) {

            [_captureSession addInput:newvideoInput];

            videoInput = newvideoInput;

        } else {

            [_captureSession addInput:videoInput];

        }
    }
    [_captureSession commitConfiguration];
    
    
    /*
    * 中间忽略 设置fps 等 activeFamat
    */
       if (isRunning) [self.captureSession startRunning];