Avant la sortie de iOS 10, j'utilisais le code suivant pour obtenir la capture vidéo et audio de mon enregistreur vidéo:
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
}
}
}
Lorsque iOS 10 est enfin sorti, j'ai reçu l'avertissement suivant lorsque j'exécutais mon code. Notez que mon enregistreur vidéo fonctionnait toujours sans à-coups pendant environ deux semaines.
'devices ()' est obsolète dans iOS 10.0: utilisez plutôt AVCaptureDeviceDiscoverySession.
Alors que je courais mon code ce matin, mon enregistreur vidéo a cessé de fonctionner. xCode8 ne me donne pas d'erreurs mais la previewLayer pour la capture de la caméra est complètement blanche. Lorsque je commence à enregistrer, le message d'erreur suivant s'affiche:
Error Domain = AVFoundationErrorDomain Code = -11800 "L'opération n'a pas pu être complétée" UserInfo = {NSLocalizedDescription = L'opération n'a pas pu être terminée, NSUnderlyingError = 0x17554440 {Domaine d'erreur = NSOSStatusErrorDomain Code = -12780 "(null)"}, NSLocalizedReprotection erreur inconnue survenue (-12780)}
Je pense que cela a quelque chose à voir avec le fait que j'utilise l'approche obsolète AVCaptureDevice.devices()
. Par conséquent, je me demandais comment utiliser AVCaptureDeviceDiscoverySession
à la place?
Merci d'avance pour votre aide!
Vous pouvez obtenir la caméra frontale avec les éléments suivants:
AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .front)
La caméra de recul:
AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)
Et le micro:
AVCaptureDevice.default(.builtInMicrophone, for: AVMediaType.audio, position: .unspecified)
Swift 4, iOS 10+ et Xcode 10.1 remplace
if let cameraID = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)?.localizedName {
//cameraID = "Front Camera"
}
avec AVCaptureDevice.DiscoverySession implementation
if let cameraID = AVCaptureDevice.DiscoverySession.init(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: .video, position: .front).devices.first?.localizedName{
//cameraID = "Front Camera"
}
Besoin de l'envelopper avec #available (iOS 10, *) check.
Voici mon code (Swift 3) pour obtenir la position de la caméra:
// 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
}
Si vous le souhaitez, vous pouvez également obtenir les nouveaux types devicesTypes de l'iPhone 7+ (double caméra) en modifiant le tableau deviceTypes.
Voici une bonne lecture: https://forums.developer.Apple.com/thread/63347
Cela fonctionne sur Xcode 9.2 et Swift 4
AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back)
https://developer.Apple.com/documentation/avfoundation/avcapturedevice/2361508- par défaut
Swift 3
Pour sélectionner la caméra de recul: (vous pouvez aussi changer .back au besoin)
Pour sélectionner un autre deviceType simple, ajoutez-le à l'intérieur du [] (c'est-à-dire:
[deviceTypeCamera, AVCaptureDeviceType.builtInMicrophone]
(ou créer un let privé ... comme je l'ai fait dans le code avec la caméra de recul)
private let position = AVCaptureDevicePosition.back
private let deviceTypeBackCamera = AVCaptureDeviceType.builtInWideAngleCamera
private func selectCaptureDevice() -> AVCaptureDevice? {
return AVCaptureDeviceDiscoverySession(deviceTypes: [deviceTypeBackCamera], mediaType: AVMediaTypeVideo, position: position).devices.first
}
exemple: 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()
Essayez le code ci-dessous pour obtenir l'identifiant de la caméra:
NSString *cameraID = nil;
NSArray *captureDeviceType = @[AVCaptureDeviceTypeBuiltInWideAngleCamera];
AVCaptureDeviceDiscoverySession *captureDevice =
[AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:captureDeviceType
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified];
cameraID = [captureDevice.devices.lastObject localizedName];
Pour mon application de capture vidéo, j'utilise le code suivant pour obtenir le micro, les caméras avant et arrière et j'ai testé ce code de 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
}
}
Swift 4 (xCode 10.1)
C'est ce qui a fonctionné pour moi dans la dernière version de Swift. Je n’ai pas vu cette réponse, et il m’a fallu un certain temps pour comprendre, voici comment obtenir la caméra frontale.
if let device = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera , mediaType: AVMediaTypeVideo, position: .front) {
//Do the camera thing here..
}