基本上我要做的就是让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)")
}
}
答案 0 :(得分:2)
如果您只需要根据简单的特征找到单个设备(例如可以拍摄视频的前置摄像头),只需使用AVCaptureDevice
。defaultDevice(withDeviceType:mediaType:position:)
。例如:
guard let device = AVCaptureDevice.defaultDevice(
withDeviceType: .builtInWideAngleCamera,
mediaType: AVMediaTypeVideo,
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
对于大多数用例来说,确实是这样。
还有AVCaptureDeviceDiscoverySession
作为迭代devices
数组的旧方法的替代品。但是,您可以使用新的defaultDevice(withDeviceType:mediaType:position:)
方法找到您通常遍历devices
数组的大部分内容,因此您可以使用它并编写更少的代码。
AVCaptureDeviceDiscoverySession
值得使用的情况是不太常见,更复杂的情况:假设您想要找到支持特定帧速率的所有设备,或者使用键值观察来查看何时设置可用的设备更改。
顺便说一句......
我已经浏览了StackOverflow,从iOS 10,Swift 3和Xcode 8开始,所有提供的方法和答案都已弃用。
如果您阅读Apple的这些方法的文档(至少this one,this one和this one),您会看到一些弃用警告建议使用什么代替。还有a guide到iOS 10 / Swift 3照片捕获系统,还有一些sample code都显示了这些API的当前最佳做法。
答案 1 :(得分:0)
如果您明确需要前置摄像头,可以使用此处指定的AVCaptureDeviceDiscoverySession。
https://developer.apple.com/reference/avfoundation/avcapturedevicediscoverysession/2361539-init
这允许您指定要搜索的设备类型。以下(未经测试)应该为您提供前置摄像头。
let deviceSessions = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
此deviceSessions具有devices属性,该属性是AVCaptureDevice类型的数组,仅包含与该搜索条件匹配的设备。
deviceSessions?.devices
这应该是0或1,具体取决于设备是否具有前置摄像头(例如某些iPod不会)。