iOS - 采集音视频及写入文件
2017-07-15 22:20
169 查看
音视频采集包括两部分:视频采集和音频采集。在iOS中可以同步采集视频与音频,通过系统框架AVFoundation,可以帮助我们采集音频与视频,对于视频还可以进行切换前后摄像头,最终我们将录制好的视频写入沙盒中
设置视频输入源与输出源
设置音频的输入源与输出源
添加音频与视频的输入与输出到session中,但是每次添加之前需要先判断是否可以添加
现在基本功能都有了,如果想要开始采集音视频只需要调用
在开始采集音视频的时候就要开始写入文件
在停止采集音视频的时候停止写入文件
详情请看 DEMO
音视频数据的采集与展示
一、初始化视频的输入与输出
// 懒加载一个session,所有的操作都需要session来执行 fileprivate lazy var session: AVCaptureSession = AVCaptureSession() // 保存视频输出 fileprivate var videoOutput: AVCaptureVideoDataOutput? // 保存视频输入 fileprivate var videoInput: AVCaptureDeviceInput? // 保存预览图层 fileprivate var previewLayer: AVCaptureVideoPreviewLayer?
设置视频输入源与输出源
// 设置视频输入源 guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else { return } // 获取我们的前置摄像头(后置为.back) guard let device = devices.filter({ $0.position == .front }).first else { return } guard let input = try? AVCaptureDeviceInput(device: device) else { return } self.videoInput = input // 设置视频输出源 let output = AVCaptureVideoDataOutput() let queue = DispatchQueue.global() // 设置代理,并在代理中获取采集到的数据,需要遵守 AVCaptureVideoDataOutputSampleBufferDelegate output.setSampleBufferDelegate(self, queue: queue) self.videoOutput = output
设置音频的输入源与输出源
// 设置音频的输入源 guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else { return } guard let input = try? AVCaptureDeviceInput(device: device) else {return} // 设置音频输出源 let output = AVCaptureAudioDataOutput() let queue = DispatchQueue.global() // 需要遵守 AVCaptureAudioDataOutputSampleBufferDelegate output.setSampleBufferDelegate(self, queue: queue)
添加音频与视频的输入与输出到session中,但是每次添加之前需要先判断是否可以添加
// 添加输入与输出 // 注意:每次对session进行设置之前都需要调用session的【beginConfiguration】方法 // 来告诉系统你现在要开始进行配置,结束配置后再调用【commitConfiguration】方法来提交配置 session.beginConfiguration() if session.canAddInput(input) { session.addInput(input) } if session.canAddOutput(output) { session.addOutput(output) } session.commitConfiguration()
二、实现音视频的采集代理
音视频虽然需要遵守的代理名称不一样,但是需要实现的方法是一致的,所以要拿到音频或者视频就得先进行判断,需要用到AVCaptureOutput的这个方法// This convenience method returns the first AVCaptureConnection in the receiver's // connections array that has an AVCaptureInputPort of the specified mediaType. If // no connection with the specified mediaType is found, nil is returned. open func connection(withMediaType mediaType: String!) -> AVCaptureConnection!
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate { func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { if videoOutput?.connection(withMediaType: AVMediaTypeVideo) == connection { print("视频数据") } else { print("音频数据") } } }
三、初始化一个预览图层用来显示采集到的视频(非采集所必须的步骤)
// 创建预览图层 guard let previewLayer = AVCaptureVideoPreviewLayer(session: session) else {return} previewLayer.frame = view.bounds // 将图层添加到控制器的view的layer中 view.layer.insertSublayer(previewLayer, at: 0) self.previewLayer = previewLayer
现在基本功能都有了,如果想要开始采集音视频只需要调用
// 开始录制 session.startRunning() // 结束录制 session.stopRunning()
切换镜头
其实就是换掉当前的视频输入法制,这里的过程跟上面的设置输入源一样。// 1.取出之前镜头的方向 guard let videoInput = videoInput else { return } let position: AVCaptureDevicePosition = videoInput.device.position == .front ? .back : .front guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else { return } guard let device = devices.filter({ $0.position == position }).first else { return } guard let newInput = try? AVCaptureDeviceInput(device: device) else { return } // 2.移除之前的input,添加新的input session.beginConfiguration() session.removeInput(videoInput) if session.canAddInput(newInput) { session.addInput(newInput) } session.commitConfiguration() // 3.保存最新的input self.videoInput = newInput
录制视频写入文件
fileprivate var movieOutput: AVCaptureMovieFileOutput?
在开始采集音视频的时候就要开始写入文件
// 开始写入文件 // 1、创建写入文件的输出 let fileOutput = AVCaptureMovieFileOutput() self.movieOutput = fileOutput // 保存起来,用于停止写入文件 // 设置类型,不然报错(这两句很重要) let connection = fileOutput.connection(withMediaType: AVMediaTypeVideo) connection?.automaticallyAdjustsVideoMirroring = true if session.canAddOutput(fileOutput) { session.addOutput(fileOutput) } // 2、直接开始写入文件 let filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/abc.mp4" let fileUrl = URL(fileURLWithPath: filePath) fileOutput.startRecording(toOutputFileURL: fileUrl, recordingDelegate: self)
在停止采集音视频的时候停止写入文件
// 停止写入文件 movieOutput?.stopRecording()
详情请看 DEMO
相关文章推荐
- iOS 音视频采集以及写入文件(swift)
- iOS ffmpeg将音视频写入文件aac+h264
- iOS GPUImage研究五:短视频拍摄(滤镜、文件写入)
- ios 通过调用系统摄像头拍照,拍视频,然后写入文件
- ios 通过调用系统摄像头拍照,拍视频,然后写入文件
- 采集视频并写入文件
- iOS视频采集(二)
- iOS 选择图片过滤掉视频文件
- iOS 对网络视频采集视频截图
- iOS - 小文件下载篇(边下载边写入文件)
- ios直播技术(1)-- 视频采集
- iOS 录视频,相册选择视频,视频压缩,存储本地文件,播放,上传
- Unity3D研究院之IOS Android支持中文与本地文件的读取写入
- ios将图片文件写入相册目录
- 给图片文件写入exif信息(ios)
- 写入视频文件
- [ios]如何使用 Xcode,读取和写入存在的数据库文件?
- iOS视频采集(三)
- iOS 如何拿到相册中的视频文件
- iOS真机播放MP4视频文件不出来的解决方法 AVPlayer