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

42,787

Solution 1

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)

Solution 2

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

// 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.

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

Solution 3

Swift 4, iOS 10+ and Xcode 10.1 replaces

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

with AVCaptureDevice.DiscoverySession implementation

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.

Solution 4

It works on Xcode 9.2 and Swift 4

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

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

Solution 5

Swift 3

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

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

[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

 }
Share:
42,787
arauter
Author by

arauter

Updated on March 11, 2021

Comments

  • arauter
    arauter about 3 years

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

     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.

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

    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:

    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)}

    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 AVCaptureDeviceDiscoverySession instead?

    Thank you for your help in advance!

  • arauter
    arauter over 7 years
    Turned out that my camera on my iPhone was broken, hence the white color showing in the preview layer. Thank you for your answer though, at least I could get rid of my warning xcode8 was constantly giving me.
  • fi12
    fi12 over 7 years
    Do you know how to do the same thing using the back camera with Objective-C instead?
  • hefgi
    hefgi over 7 years
    You still get the deprecated warning with AVCaptureDevice.devicesWithMediaType
  • epx
    epx almost 7 years
    Xcode 9 just asked to me use __deviceTypes: instead of deviceTypes:, apart from that, it works.
  • justdan0227
    justdan0227 about 6 years
    Anyone finding that this does not work with the latest beta 11.3 SDK on 10+ phones? This works on my phone but non of my testflight testers phone the video preview layer is not getting created.
  • esco_
    esco_ about 6 years
    Code for the discovery session should now be: if let cameraID = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.front).devices.first?.localizedName‌​{ //cameraID = "Front Camera" } AVCaptureDeviceType was replaced by AVCaptureDevice.DeviceType and AVCaptureDevicePosition was replaced by AVCaptureDevice.Position (XCode 9.2 / Swift 4)
  • Ricardo Ruiz Romero
    Ricardo Ruiz Romero over 5 years
    The devices array is empty, do you know why?
  • ndreisg
    ndreisg over 3 years
    It seems all answers are using .builtInWideAngleCamera as device type. Can you explain why you use this type and not one of the many others? For example there is also .builtInDualWideCamera. Will a dual wide camera still be returned with your code?
  • Ali Amin
    Ali Amin over 2 years
    @ndreisg you can find the answer in Apples documentation developer.apple.com/documentation/avfoundation/…
  • Mostafa ElShazly
    Mostafa ElShazly almost 2 years
    @AliAmin this link has the best approach to getting the best camera available. ps: you should add the option for triple camera before the dual one for the best results as that link seems a bit old