本文将继续为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好像并不能满足需求.