##画面采集 导入AVFoundation 1.在Main.storyboard上拖入3个按钮,一个是开始录制
,一个是暂停录制
,一个是旋转镜头
.
startCapture
, stopCapture
, rotateCamera
3.采集画面 // 创建一个录制会话对象 fileprivate lazy var session : AVCaptureSession = AVCaptureSession()复制代码
// 创建一个预览图层 fileprivate lazy var preViewLayer : AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.session)复制代码
// 创建全局队列 fileprivate lazy var queue = DispatchQueue.global() fileprivate lazy var audioQueue = DispatchQueue.global()复制代码
// 创建视频输入源 fileprivate var videoInput : AVCaptureDeviceInput? // 创建视频输出源 fileprivate var videoOutPut : AVCaptureVideoDataOutput? // 创建音频输入源 fileprivate var audioInput : AVCaptureDeviceInput? // 创建音频输出源 fileprivate var audioOutPut : AVCaptureAudioDataOutput?复制代码
开始采集画面
fileprivate func setUpVideo(){ // 会话输入源(获取摄像头) // 获取设备 guard let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] else { print("模拟器无效") return } // 获取前置摄像头 guard let deviece = devices.filter({ $0.position == .front }).first else { return } // 获取AVCaptureDeviceInput 输入源 guard let input : AVCaptureDeviceInput = try? AVCaptureDeviceInput(device: deviece) else { return } // 设置视频输入源 全局变量 self.videoInput = input // 判断视频会话对象是否能添加输入源 if self.session.canAddInput(input){ self.session.addInput(input) } // 会话输出源 let outPut : AVCaptureVideoDataOutput = AVCaptureVideoDataOutput() // 设置输出源的代理 outPut.setSampleBufferDelegate(self, queue: self.queue) // 判断视频录制会话对象是否能添加输出源 if self.session.canAddOutput(outPut){ self.session.addOutput(outPut) } self.videoOutPut = outPut复制代码
旋转镜头
// 添加镜头旋转的动画@IBAction func rotateCamera(_ sender: AnyObject) { // 添加旋转摄像头的动画 let rotaionAnim = CATransition() rotaionAnim.type = "oglFlip" rotaionAnim.subtype = "fromLeft" rotaionAnim.duration = 0.5 view.layer.add(rotaionAnim, forKey: nil) // 获取之前的镜头 guard var position = self.videoInput?.device.position else { return} // 设置相反的位置的镜头 position = position == .front ? .back : .front // 根据现在摄像头的位置创建新的device let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) as? [AVCaptureDevice] guard let device = devices?.filter({ $0.position == position}).first else { return} // 创建新的输入源 guard let input = try? AVCaptureDeviceInput(device: device) else { return} // 在session中切换input session.beginConfiguration() session.removeInput(self.videoInput) if session.canAddInput(self.videoInput) { session.addInput(input) } self.videoInput = input session.commitConfiguration()}复制代码
4.采集音频
fileprivate func setUpAudio(){ // 创建音频输入源(话筒) // 获取设备 guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else { return} // 创建输入源 guard let input = try? AVCaptureDeviceInput(device: device) else { return} self.audioInput = input // 判断是否能添加输入源 if session.canAddInput(input) { session.addInput(input) } // 创建输出源 let outPut = AVCaptureAudioDataOutput() // 设置代理 outPut.setSampleBufferDelegate(self, queue: self.audioQueue) self.audioOutPut = outPut // 判断是否能添加输出源 if session.canAddOutput(outPut){ session.addOutput(outPut) }// 复制代码
遵守音频录制和视频录制的代理,两个代理方法是同一个
// 遵守录制视频输出会话的代理,sampleBuffer就是美颜所修改的东西extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{ func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { if connection == self.videoOutPut?.connection(withMediaType: AVMediaTypeVideo) { print("输出视频画面") }else{ print("获取音频!") } } }复制代码
5.停止录制
// 停止录制 @IBAction func stopCapture(_ sender: AnyObject) { self.session.stopRunning() self.preViewLayer.removeFromSuperlayer() self.fileOutPut?.stopRecording() // 移除输入源和舒楚媛 self.session.removeInput(self.videoInput) self.session.removeOutput(self.videoOutPut) self.session.removeInput(self.audioInput) self.session.removeOutput(self.audioOutPut) self.session.removeOutput(self.fileOutPut) }复制代码
将程序跑到真机上,点击开始录制即可以录制成功!