How to get front camera, back camera and audio with AVCaptureDeviceDiscoverySession
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
}
arauter
Updated on March 11, 2021Comments
-
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 useAVCaptureDeviceDiscoverySession
instead?Thank you for your help in advance!
-
arauter over 7 yearsTurned 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 over 7 yearsDo you know how to do the same thing using the back camera with Objective-C instead?
-
hefgi over 7 yearsYou still get the deprecated warning with AVCaptureDevice.devicesWithMediaType
-
epx almost 7 yearsXcode 9 just asked to me use __deviceTypes: instead of deviceTypes:, apart from that, it works.
-
justdan0227 about 6 yearsAnyone 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_ about 6 yearsCode 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 byAVCaptureDevice.DeviceType
andAVCaptureDevicePosition
was replaced byAVCaptureDevice.Position
(XCode 9.2 / Swift 4) -
Ricardo Ruiz Romero over 5 yearsThe devices array is empty, do you know why?
-
ndreisg over 3 yearsIt 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 over 2 years@ndreisg you can find the answer in Apples documentation developer.apple.com/documentation/avfoundation/…
-
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