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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:16:36  来源:igfitidea点击:

How to get the front camera in Swift?

iosiphoneswift

提问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 AVCaptureDeviceDiscoverySessionas a replacement for the old method of iterating through the devicesarray. However, most of the things you'd usually iterate through the devicesarray 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 AVCaptureDeviceDiscoverySessionis 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 .filterfollowed by .firstisn'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)
    }

回答by jnblanchard

##代码##

回答by Amul4608

##代码##