切换摄像头

本文将继续为Kcamera项目添加切换摄像头功能,文中的代码可以在https://github.com/changjianfeishui/Kcamera上找到.

在CaptureModel中添加与切换摄像头相关的代码如下:

//MARK: - 切换摄像头    
//获取设备的摄像头数量
func cameraCount() -> Int {
    return AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo).count
}

//只有摄像头数量大于1个时,才能进行切换
func canSwitchCamera() -> Bool {
    return self.cameraCount() > 1
}

//切换摄像头
func switchCameras() -> Bool {
    //1. 判断是否能够切换摄像头
    if !self.canSwitchCamera() {
        return false
    }
    //2. 获取闲置的摄像头
    var device:AVCaptureDevice
    if self.activeVideoInput.device.position == .Back {
        device = self.cameraWithPosition(.Front)!
    }else{
        device = self.cameraWithPosition(.Back)!
    }

    //3. 把采集设备封装为一个AVCaptureDeviceInput对象
    let videoInput = try? AVCaptureDeviceInput(device: device)

    if videoInput != nil {
        //4. 开始重新配置捕捉会话
        self.captureSession.beginConfiguration()
        //5. 移除当前的输入对象
        self.captureSession.removeInput(self.activeVideoInput)
        //6. 添加新的输入对象
        if self.captureSession.canAddInput(videoInput) {
            self.captureSession.addInput(videoInput)
            self.activeVideoInput = videoInput

        }else{
            //7. 如果添加失败,回滚配置
            self.captureSession.addInput(self.activeVideoInput)
        }
        //8. 提交配置
        self.captureSession.commitConfiguration()


    }else{
        return false
    }
    return true

}

//根据position返回可用的摄像头
func cameraWithPosition(position:AVCaptureDevicePosition) -> AVCaptureDevice? {
    let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]
    for device in devices {
        if device.position == position {
            return device
        }
    }
    return nil
}

测试

参见Github上的Kcamera,打开Main.storyboard,在根View上添加一个切换摄像头的UIButton.

将上面切换摄像头的Button的点击与ViewController联系起来:

//切换摄像头
@IBAction func switchCamera(sender: UIButton) {
    self.captureModel.switchCameras()
}

编译运行程序,切换摄像头,进行视频录制或拍照.

补充

测试发现, 在录制过程中切换摄像头, 会导致录制中断, 相册中只保留切换前的一段视频.

尽管Apple在文档中描述:

Sometimes you may want to allow users to switch between input devices—for example, switching from using the front-facing to to the back-facing camera. To avoid pauses or stuttering, you can reconfigure a session while it is running, however you should use beginConfiguration and commitConfiguration to bracket your configuration changes:

AVCaptureSession *session = <#A capture session#>;
[session beginConfiguration]; 
[session removeInput:frontFacingCameraDeviceInput];
[session addInput:backFacingCameraDeviceInput];
[session commitConfiguration];

When the outermost commitConfiguration is invoked, all the changes are made together. This ensures a smooth transition.

但经过尝试发现,AVCaptureMovieFileOutput好像并不能满足需求.