Je suis la seule réponse que cela a sur SO -
Changer de caméra avec avcapturesession
Cependant, cameraWithPosition ne semble pas fonctionner. Obsolète?
//Get new input
AVCaptureDevice *newCamera = nil;
if(((AVCaptureDeviceInput*)currentCameraInput).device.position == AVCaptureDevicePositionBack)
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
}
else
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
}
Ce que vous devez faire est de reconfigurer votre AVCaptureSession
Voici ce que j'utilise:
// note that `AVCaptureSession * session`
//
if(session)
{
[session beginConfiguration];
AVCaptureInput *currentCameraInput = [session.inputs objectAtIndex:0];
[session removeInput:currentCameraInput];
AVCaptureDevice *newCamera = nil;
if(((AVCaptureDeviceInput*)currentCameraInput).device.position == AVCaptureDevicePositionBack)
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
}
else
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
}
NSError *err = nil;
AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
if(!newVideoInput || err)
{
NSLog(@"Error creating capture device input: %@", err.localizedDescription);
}
else
{
[session addInput:newVideoInput];
}
[session commitConfiguration];
}
// make sure you have this method in your class
//
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices)
{
if ([device position] == position)
return device;
}
return nil;
}
Dans Swift 3.0
/// Swap camera and reconfigures camera session with new input
fileprivate func swapCamera() {
// Get current input
guard let input = cameraSession.inputs[0] as? AVCaptureDeviceInput else { return }
// Begin new session configuration and defer commit
cameraSession.beginConfiguration()
defer { cameraSession.commitConfiguration() }
// Create new capture device
var newDevice: AVCaptureDevice?
if input.device.position == .back {
newDevice = captureDevice(with: .front)
} else {
newDevice = captureDevice(with: .back)
}
// Create new capture input
var deviceInput: AVCaptureDeviceInput!
do {
deviceInput = try AVCaptureDeviceInput(device: newDevice)
} catch let error {
print(error.localizedDescription)
return
}
// Swap capture device inputs
cameraSession.removeInput(input)
cameraSession.addInput(deviceInput)
}
/// Create new capture device with requested position
fileprivate func captureDevice(with position: AVCaptureDevicePosition) -> AVCaptureDevice? {
let devices = AVCaptureDeviceDiscoverySession(deviceTypes: [ .builtInWideAngleCamera, .builtInMicrophone, .builtInDualCamera, .builtInTelephotoCamera ], mediaType: AVMediaTypeVideo, position: .unspecified).devices
if let devices = devices {
for device in devices {
if device.position == position {
return device
}
}
}
return nil
}
Voici un exemple d'utilisation du commutateur avec une session vidéo:
.h
UIViewController<AVCaptureFileOutputRecordingDelegate>
@property(nonatomic,strong) AVCaptureSession *CaptureSession;
@property(nonatomic,strong) AVCaptureMovieFileOutput *MovieFileOutput;
@property(nonatomic,strong) AVCaptureDeviceInput *VideoInputDevice;
- (void) CameraSetOutputProperties;
- (AVCaptureDevice *) CameraWithPosition:(AVCaptureDevicePosition) Position;
Ensuite:
.m
- (void)viewDidLoad {
[super viewDidLoad];
CaptureSession = [[AVCaptureSession alloc] init];
//etc
}
- (IBAction)CameraToggle:(id)sender
{
if ([[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count] > 1) //Only do if device has multiple cameras
{
NSError *error;
//AVCaptureDeviceInput *videoInput = [self videoInput];
AVCaptureDeviceInput *NewVideoInput;
AVCaptureDevicePosition position = [[VideoInputDevice device] position];
if (position == AVCaptureDevicePositionBack)
{
NewVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self CameraWithPosition:AVCaptureDevicePositionFront] error:&error];
}
else if (position == AVCaptureDevicePositionFront)
{
NewVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self CameraWithPosition:AVCaptureDevicePositionBack] error:&error];
}
if (NewVideoInput != nil)
{
[CaptureSession beginConfiguration];
[CaptureSession removeInput:VideoInputDevice];
if ([CaptureSession canAddInput:NewVideoInput])
{
[CaptureSession addInput:NewVideoInput];
VideoInputDevice = NewVideoInput;
}
else
{
[CaptureSession addInput:VideoInputDevice];
}
//Set the connection properties again
[self CameraSetOutputProperties];
[CaptureSession commitConfiguration];
}
}
}
Mise à jour du code pour Swift 4.2
/// Swap camera and reconfigures camera session with new input
fileprivate func swapCamera() {
// Get current input
guard let input = captureSession.inputs[0] as? AVCaptureDeviceInput else { return }
// Begin new session configuration and defer commit
captureSession.beginConfiguration()
defer { captureSession.commitConfiguration() }
// Create new capture device
var newDevice: AVCaptureDevice?
if input.device.position == .back {
newDevice = captureDevice(with: .front)
} else {
newDevice = captureDevice(with: .back)
}
// Create new capture input
var deviceInput: AVCaptureDeviceInput!
do {
deviceInput = try AVCaptureDeviceInput(device: newDevice!)
} catch let error {
print(error.localizedDescription)
return
}
// Swap capture device inputs
captureSession.removeInput(input)
captureSession.addInput(deviceInput)
}
/// Create new capture device with requested position
fileprivate func captureDevice(with position: AVCaptureDevice.Position) -> AVCaptureDevice? {
let devices = AVCaptureDevice.DiscoverySession(deviceTypes: [ .builtInWideAngleCamera, .builtInMicrophone, .builtInDualCamera, .builtInTelephotoCamera ], mediaType: AVMediaType.video, position: .unspecified).devices
//if let devices = devices {
for device in devices {
if device.position == position {
return device
}
}
//}
return nil
}