自动将前置摄像头用于AVCaptureDevice预览层,如Snapchat或Houseparty(Swift 3)

自动将前置摄像头用于AVCaptureDevice预览层,如Snapchat或Houseparty(Swift 3),swift,swift3,avfoundation,xcode8,avcapturesession,Swift,Swift3,Avfoundation,Xcode8,Avcapturesession,基本上,我试图实现的是让AVCaptureDevice的前置摄像头成为AVCaptureSession期间应用程序的第一个也是唯一的选项 我环顾了StackOverflow,所有提供的方法和答案在iOS 10、Swift 3和Xcode 8之后都不推荐使用 我知道你应该列举带有AVCaptureDeviceDiscoverySession的设备,并查看它们以区分正面和背面,但我不确定如何做到这一点 有人能帮忙吗?如果是这样的话,那就太神奇了 这是我的密码: override func v

基本上,我试图实现的是让AVCaptureDevice的前置摄像头成为AVCaptureSession期间应用程序的第一个也是唯一的选项

我环顾了StackOverflow,所有提供的方法和答案在iOS 10、Swift 3和Xcode 8之后都不推荐使用

我知道你应该列举带有AVCaptureDeviceDiscoverySession的设备,并查看它们以区分正面和背面,但我不确定如何做到这一点

有人能帮忙吗?如果是这样的话,那就太神奇了

这是我的密码:

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    previewLayer.frame = singleViewCameraSlot.bounds
    self.singleViewCameraSlot.layer.addSublayer(previewLayer)
    captureSession.startRunning()

}



lazy var captureSession: AVCaptureSession = {
    let capture = AVCaptureSession()
    capture.sessionPreset = AVCaptureSessionPreset1920x1080
    return capture
}()

lazy var previewLayer: AVCaptureVideoPreviewLayer = {
    let preview =  AVCaptureVideoPreviewLayer(session: self.captureSession)

    preview?.videoGravity = AVLayerVideoGravityResizeAspect
    preview?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
    preview?.bounds = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
    preview?.position = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)

    return preview!
}()


func setupCameraSession() {


    let frontCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) as AVCaptureDevice

    do {
        let deviceInput = try AVCaptureDeviceInput(device: frontCamera)

        captureSession.beginConfiguration()

        if (captureSession.canAddInput(deviceInput) == true) {
            captureSession.addInput(deviceInput)
        }

        let dataOutput = AVCaptureVideoDataOutput()

        dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange as UInt32)]
        dataOutput.alwaysDiscardsLateVideoFrames = true

        if (captureSession.canAddOutput(dataOutput) == true) {
            captureSession.addOutput(dataOutput)
        }

        captureSession.commitConfiguration()

        let queue = DispatchQueue(label: "io.goodnight.videoQueue")
        dataOutput.setSampleBufferDelegate(self, queue: queue)

    }
    catch let error as NSError {
        NSLog("\(error), \(error.localizedDescription)")
    }

}

如果明确需要前置摄像头,可以使用此处指定的AVCaptureDeviceDiscoverySession

这允许您指定要搜索的设备类型。以下(未测试)应为您提供前置摄像头

let deviceSessions = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
此deviceSessions具有devices属性,该属性是AVCaptureDevice类型的数组,仅包含与该搜索条件匹配的设备

deviceSessions?.devices

该值应为0或1,具体取决于设备是否有前置摄像头(例如,某些iPod不会)。如果您明确需要前置摄像头,可以使用此处指定的AVCaptureDeviceDiscoverySession

这允许您指定要搜索的设备类型。以下(未测试)应为您提供前置摄像头

let deviceSessions = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
此deviceSessions具有devices属性,该属性是AVCaptureDevice类型的数组,仅包含与该搜索条件匹配的设备

deviceSessions?.devices

这应该是0或1,这取决于设备是否有前置摄像头(例如,某些iPod不会)。

如果您只需要根据简单的特性找到单个设备(如可以拍摄视频的前置摄像头),只需使用
AVCaptureDevice
。。例如:

guard let device = AVCaptureDevice.default(.builtInWideAngleCamera,
    for: .video,
    position: .front)
    else { fatalError("no front camera. but don't all iOS 10 devices have them?")

// then use the device: captureSession.addInput(device) or whatever
实际上,这就是大多数用例的全部内容


还有一种方法可以替代在
设备
数组中迭代的旧方法。但是,您通常通过
设备
数组迭代的大部分内容都可以使用新方法找到,因此您最好使用新方法并编写更少的代码

值得使用的情况是不太常见、更复杂的情况:假设您希望找到支持特定帧速率的所有设备,或者使用键值观察查看可用设备集何时更改


顺便说一下

我环顾了StackOverflow,所有提供的方法和答案在iOS 10、Swift 3和Xcode 8之后都不推荐使用


如果你阅读苹果的文档了解这些方法(至少,和),你会看到一些建议,以及那些不推荐使用的警告。iOS 10/Swift 3照片捕获系统和一些都显示了这些API的当前最佳实践。

如果您只需要根据简单的特性找到单个设备(如可以拍摄视频的前置摄像头),只需使用
AVCaptureDevice
。。例如:

guard let device = AVCaptureDevice.default(.builtInWideAngleCamera,
    for: .video,
    position: .front)
    else { fatalError("no front camera. but don't all iOS 10 devices have them?")

// then use the device: captureSession.addInput(device) or whatever
实际上,这就是大多数用例的全部内容


还有一种方法可以替代在
设备
数组中迭代的旧方法。但是,您通常通过
设备
数组迭代的大部分内容都可以使用新方法找到,因此您最好使用新方法并编写更少的代码

值得使用的情况是不太常见、更复杂的情况:假设您希望找到支持特定帧速率的所有设备,或者使用键值观察查看可用设备集何时更改


顺便说一下

我环顾了StackOverflow,所有提供的方法和答案在iOS 10、Swift 3和Xcode 8之后都不推荐使用

如果你阅读苹果的文档了解这些方法(至少,和),你会看到一些建议,以及那些不推荐使用的警告。iOS 10/Swift 3照片捕获系统还有一些功能,它们都显示了这些API的当前最佳实践