ios 如何使用 AVCaptureDeviceDiscoverySession 获取前置摄像头、后置摄像头和音频

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39894630/
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 10:29:53  来源:igfitidea点击:

How to get front camera, back camera and audio with AVCaptureDeviceDiscoverySession

iosswiftavfoundationavcapturedevice

提问by AndreasLukas

Before iOS 10 came out I was using the following code to get the video and audio capture for my video recorder:

在 iOS 10 出现之前,我使用以下代码来获取我的录像机的视频和音频捕获:

 for device in AVCaptureDevice.devices()
 {
     if (device as AnyObject).hasMediaType( AVMediaTypeAudio )
     {
         self.audioCapture = device as? AVCaptureDevice
     }
     else if (device as AnyObject).hasMediaType( AVMediaTypeVideo )
     {
         if (device as AnyObject).position == AVCaptureDevicePosition.back
         {
             self.backCameraVideoCapture = device as? AVCaptureDevice
         }
         else
         {
             self.frontCameraVideoCapture = device as? AVCaptureDevice
         }
     }
 }

When iOS 10 finally came out, I received the following warning when I was running my code. Note that my video recorder was still working smoothly for about 2 weeks.

当 iOS 10 终于出来时,我在运行我的代码时收到以下警告。请注意,我的录像机在大约 2 周内仍能正常工作。

'devices()' was deprecated in iOS 10.0: Use AVCaptureDeviceDiscoverySession instead.

'devices()' 在 iOS 10.0 中被弃用:改用 AVCaptureDeviceDiscoverySession。

As I was running my code this morning, my video recorder stopped working. xCode8 does not give me any errors but the previewLayer for the camera capture is completely white. When I then start recording I receive the following error:

当我今天早上运行我的代码时,我的录像机停止工作。xCode8 没有给我任何错误,但相机捕获的 previewLayer 是完全白色的。当我开始录制时,我收到以下错误:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17554440 {Error Domain=NSOSStatusErrorDomain Code=-12780 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12780)}

Error Domain=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo={NSLocalizedDescription=操作无法完成,NSUnderlyingError=0x17554440 {Error Domain=NSOSStatusErrorDomain Code=-12780 "(null)"},NSLocalizedFailureReason=An发生未知错误 (-12780)}

I believe that has something to do with the fact that I am using the deprecated approach AVCaptureDevice.devices(). Hence, I was wondering how to use AVCaptureDeviceDiscoverySessioninstead?

我相信这与我使用已弃用方法这一事实有关AVCaptureDevice.devices()。因此,我想知道如何使用AVCaptureDeviceDiscoverySession

Thank you for your help in advance!

提前谢谢你的帮助!

回答by born_stubborn

You can get the front camera with the following:

您可以通过以下方式获得前置摄像头:

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .front)

The back camera:

后置摄像头:

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)

And the microphone:

还有麦克风:

AVCaptureDevice.default(.builtInMicrophone, for: AVMediaType.audio, position: .unspecified)

回答by hefgi

Here's my code (Swift 3) to get camera position :

这是我获取相机位置的代码(Swift 3):

// Find a camera with the specified AVCaptureDevicePosition, returning nil if one is not found
func cameraWithPosition(_ position: AVCaptureDevicePosition) -> AVCaptureDevice?
{
    if let deviceDescoverySession = AVCaptureDeviceDiscoverySession.init(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera],
                                                          mediaType: AVMediaTypeVideo,
                                                          position: AVCaptureDevicePosition.unspecified) {

        for device in deviceDescoverySession.devices {
            if device.position == position {
                return device
            }
        }
    }

    return nil
}

If you want, you can also get the new devicesTypes from iPhone 7+ (dual camera) by changing the deviceTypes array.

如果需要,您还可以通过更改 deviceTypes 数组从 iPhone 7+(双摄像头)获取新的 devicesTypes。

Here's a good read : https://forums.developer.apple.com/thread/63347

这是一个很好的阅读:https: //forums.developer.apple.com/thread/63347

回答by Rafat touqir Rafsun

Swift 4, iOS 10+ and Xcode 10.1replaces

Swift 4、iOS 10+ 和Xcode 10.1取代

if let cameraID = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)?.localizedName {
       //cameraID = "Front Camera"
}

with AVCaptureDevice.DiscoverySessionimplementation

使用AVCaptureDevice.DiscoverySession实现

if let cameraID = AVCaptureDevice.DiscoverySession.init(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: .video, position: .front).devices.first?.localizedName{
        //cameraID = "Front Camera"
} 

Need to wrap it with #available(iOS 10,*)check.

需要用#available(iOS 10,*)检查来包装它。

回答by atereshkov

It works on Xcode 9.2 and Swift 4

它适用于Xcode 9.2 和 Swift 4

AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)

https://developer.apple.com/documentation/avfoundation/avcapturedevice/2361508-default

https://developer.apple.com/documentation/avfoundation/avcapturedevice/2361508-default

回答by Harry McGovern

example: iOS 11 Swift 4

示例:iOS 11 Swift 4

override func viewDidLoad() {
    super.viewDidLoad()

    // Get the back-facing camera for capturing videos

    // AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)
    let deviceDiscoverySession = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)

   guard let captureDevice = deviceDiscoverySession else {
       print("Failed to get the camera device")
       return
   }

    do {
        // Get an instance of the AVCaptureDeviceInput class using the previous device object.
        let input = try AVCaptureDeviceInput(device: captureDevice)

        // Set the input device on the capture session.
        captureSession.addInput(input)

    } catch {
        // If any error occurs, simply print it out and don't continue any more.
        print(error)
        return
    }

    // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    videoPreviewLayer?.frame = view.layer.bounds
    view.layer.addSublayer(videoPreviewLayer!)

    // Start video capture.
    captureSession.startRunning()

回答by MLBDG

Swift 3

斯威夫特 3

For selecting the back camera:(also you can change .back as needed)

用于选择后置摄像头:(您也可以根据需要更改 .back)

For selecting another deviceType simple add it inside the [ ] (i.e:

要选择另一个 deviceType,只需将其添加到 [] 中(即:

[deviceTypeCamera, AVCaptureDeviceType.builtInMicrophone]

[deviceTypeCamera, AVCaptureDeviceType.builtInMicrophone]

(or create a private let... like I did in the code with the back camera)

(或创建一个私人让......就像我在带有后置摄像头的代码中所做的那样)

 private let position = AVCaptureDevicePosition.back
 private let deviceTypeBackCamera = AVCaptureDeviceType.builtInWideAngleCamera

 private func selectCaptureDevice() -> AVCaptureDevice? {
    return AVCaptureDeviceDiscoverySession(deviceTypes: [deviceTypeBackCamera], mediaType: AVMediaTypeVideo, position: position).devices.first

 }

回答by yoell32

Try below code to get camera ID:

尝试以下代码以获取相机 ID:

NSString *cameraID = nil;

NSArray *captureDeviceType = @[AVCaptureDeviceTypeBuiltInWideAngleCamera];
AVCaptureDeviceDiscoverySession *captureDevice = 
              [AVCaptureDeviceDiscoverySession 
                discoverySessionWithDeviceTypes:captureDeviceType 
                mediaType:AVMediaTypeVideo 
                position:AVCaptureDevicePositionUnspecified];

cameraID = [captureDevice.devices.lastObject localizedName];

回答by Hammadzafar

For my video capture app I'm using the following code to get the mic, front and rear camera and I've tested this code from iOS 7 to 10.0.2.

对于我的视频捕获应用程序,我使用以下代码来获取麦克风、前置和后置摄像头,并且我已经测试了从 iOS 7 到 10.0.2 的这段代码。

        var frontCamera : AVCaptureDevice?
        var rearCamera : AVCaptureDevice?

        captureSession = AVCaptureSession()

        let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)

        let audioDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeAudio)

        for mic in audioDevices {
            audioDevice = mic as? AVCaptureDevice
            audioCapturePossible = true
        }

        for device in devices {
            if device.position == AVCaptureDevicePosition.Front {
                frontCamera = device as? AVCaptureDevice
                hasFrontCamera = true
            }
            else if device.position == AVCaptureDevicePosition.Back {
                rearCamera = device as? AVCaptureDevice
                hasRearCamera = true
            }

        }

回答by Dave Levy

Swift 4 (xCode 10.1)

斯威夫特 4 (xCode 10.1)

This is what worked for me in the latest version of Swift. I did not see this answer, and it took me a while to suss out so here is how to get the front facing camera.

这在最新版本的 Swift 中对我有用。我没有看到这个答案,我花了一段时间才弄明白,所以这里是如何获得前置摄像头。

 if let device = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera , mediaType: AVMediaTypeVideo, position: .front)  {
    //Do the camera thing here..
}

回答by Boris Detry

05/2019 :

05/2019 :

 //video
        self.session = AVCaptureSession()
        guard
            let videoDeviceInput = try? AVCaptureDeviceInput(device: device!),
            self.session!.canAddInput(videoDeviceInput)
            else { return }
        self.session!.addInput(videoDeviceInput)

  //audio
        guard
            let audioDeviceInput = try? AVCaptureDeviceInput(device: mic!),
            self.session!.canAddInput(audioDeviceInput)
            else { return }
        self.session!.addInput(audioDeviceInput)