ios 如何在 Swift 中获取前置摄像头?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29155623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the front camera in Swift?
提问by mindfreek
I am trying to get the front camera with live view. I am able to get the back camera using:
我正在尝试使用实时取景功能获取前置摄像头。我可以使用以下方法获取后置摄像头:
var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
But I can't seem to find how to get the front camera. How can I change the code above to use the front camera?
但我似乎无法找到如何获得前置摄像头。如何更改上面的代码以使用前置摄像头?
采纳答案by chrissukhram
Here is a working example from one of my projects to get the front camera. This is in objective-c but proven to work and easy enough to convert to swift.
这是我的一个项目中的一个工作示例,用于获取前置摄像头。这是在 Objective-c 中,但被证明是有效的,并且很容易转换为 swift。
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *captureDevice = nil;
for (AVCaptureDevice *device in videoDevices){
if (device.position == AVCaptureDevicePositionFront){
captureDevice = device;
break;
}
}
And in Swift 3.2+:
在 Swift 3.2+ 中:
if let videoDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) {
var captureDevice: AVCaptureDevice
for device in videoDevices {
if let device = device as? AVCaptureDevice {
if device.position == AVCaptureDevicePosition.front {
captureDevice = device
break
}
}
}
}
回答by rickster
In iOS 10.0 and later, you don't need to iterate through AVCaptureDevice
.devices
(or devicesWithMediaType
) to find a camera by position. (In fact, both of those APIs are deprecated in iOS 10, and don't return the full set of available devices on iPhone 7 Plus, iPhone 8 Plus, or iPhone X.)
在 iOS 10.0 及更高版本中,您不需要遍历AVCaptureDevice
. devices
(或devicesWithMediaType
) 按位置查找摄像机。(实际上,这两个 API 在 iOS 10 中都已弃用,并且不会在 iPhone 7 Plus、iPhone 8 Plus 或 iPhone X 上返回完整的可用设备集。)
If you just need to find a single device based on simple characteristics (like a front-facing camera that can shoot video), just use AVCaptureDevice
.defaultDevice(withDeviceType:mediaType:position:)
. For example:
如果您只需要根据简单的特性(例如可以拍摄视频的前置摄像头)查找单个设备,只需使用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
Really that's all there is to it for most use cases.
实际上,这就是大多数用例的全部内容。
There's also AVCaptureDeviceDiscoverySession
as a replacement for the old method of iterating through the devices
array. However, most of the things you'd usually iterate through the devices
array for can be found using the new defaultDevice(withDeviceType:mediaType:position:)
method, so you might as well use that and write less code.
也 AVCaptureDeviceDiscoverySession
可以替代旧的遍历devices
数组的方法。但是,您通常在devices
数组中迭代的大部分内容都可以使用新defaultDevice(withDeviceType:mediaType:position:)
方法找到,因此您不妨使用它并编写更少的代码。
The cases where AVCaptureDeviceDiscoverySession
is worth using are the less common, more complicated cases: say you want to find all the devices that support a certain frame rate, or use key-value observing to see when the set of available devices changes.
AVCaptureDeviceDiscoverySession
值得使用的情况是不太常见、更复杂的情况:比如你想找到所有支持特定帧率的设备,或者使用键值观察来查看可用设备集何时发生变化。
By the way, Apple also has a guideto the iOS 10 / Swift 3 photo capture system and some sample codethat both show current best practices for these APIs.
顺便说一句,Apple 还提供了iOS 10 / Swift 3 照片捕获系统的指南和一些示例代码,它们都显示了这些 API 的当前最佳实践。
回答by mbuff24
guard let device = AVCaptureDevice.devices().filter({ if let cameraID = AVCaptureDevice.defaultDevice(withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)?.localizedName {
//cameraID = "Front Camera"
}
.position == .Front })
.first as? AVCaptureDevice else {
fatalError("No front facing camera found")
}
If you're looking for a shorter solution although .filter
followed by .first
isn't the most efficient
如果您正在寻找更短的解决方案,尽管.filter
其次.first
不是最有效的
回答by Rafat touqir Rafsun
Swift 4.1, iOS 10+ and Xcode 9.3replaces
Swift 4.1、iOS 10+ 和Xcode 9.3取代
if let cameraID = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.front).devices.first?.localizedName{
//cameraID = "Front Camera"
}
with AVCaptureDevice.DiscoverySessionimplementation
使用AVCaptureDevice.DiscoverySession实现
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: .front) else {
return
}
回答by zumzum
Latests is:
最新消息是:
guard let frontCamera = AVCaptureDevice.devices().first(where: { (var captureSession: AVCaptureSession?
var frontDevice: AVCaptureDevice?
var frontInput: AVCaptureInput?
if let frontDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .front).devices.first {
frontInput = try AVCaptureDeviceInput(device: frontDevice)
}
captureSession?.beginConfiguration()
if let front = frontInput, captureSession?.canAddInput(front) == true {
captureSession?.addInput(front)
}
captureSession?.commitConfiguration()
as AnyObject).position == .front }) as? AVCaptureDevice else {
fatalError("No front facing camera found")
}
回答by Paulo
Based on the solution presented by mbuff24. Array methods include .first(where:) besides .filter()
基于 mbuff24 提出的解决方案。除了 .filter() 之外,数组方法还包括 .first(where:)
import AVFoundation
import Foundation
@IBOutlet weak var imageView: UIImageView!
let captureSession = AVCaptureSession()
let stillImageOutput = AVCaptureStillImageOutput()
var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var Arrdata:[Studentdata] = []
override func viewDidLoad() {
super.viewDidLoad()
captureSession.sessionPreset = AVCaptureSessionPresetHigh
if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice]
{
for device in devices
{
if (device.hasMediaType(AVMediaTypeVideo))
{
if(device.position == AVCaptureDevicePosition.front)
{
captureDevice = device
if captureDevice != nil
{
print("Capture device found")
beginSession()
}
}
}
}
}
}
func beginSession()
{
do
{
try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
if captureSession.canAddOutput(stillImageOutput)
{
captureSession.addOutput(stillImageOutput)
}
}
catch
{
print("error: \(error.localizedDescription)")
}
guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else
{
print("no preview layer")
return
}
self.view.layer.addSublayer(previewLayer)
previewLayer.frame = self.view.layer.frame
captureSession.startRunning()
self.view.addSubview(imageView)
}