音视频采集包括两部分:视频采集和音频采集。在iOS中可以同步采集视频与音频,通过系统框架AVFoundation,可以帮助我们采集音频与视频,对于视频还可以进行切换前后摄像头,最终我们将录制好的视频写入沙盒中
+
音视频采集包括两部分:视频采集和音频采集。在iOS中可以同步采集视频与音频,通过系统框架AVFoundation,可以帮助我们采集音频与视频,对于视频还可以进行切换前后摄像头,最终我们将录制好的视频写入沙盒中
音视频数据的采集与展示 一、初始化视频的输入与输出 1 2 3 4 5 6 7 8 fileprivate lazy var session: AVCaptureSession = AVCaptureSession ()fileprivate var videoOutput: AVCaptureVideoDataOutput? fileprivate var videoInput: AVCaptureDeviceInput? fileprivate var previewLayer: AVCaptureVideoPreviewLayer?
设置视频输入源与输出源
1 2 3 4 5 6 7 8 9 10 11 12 13 guard let devices = AVCaptureDevice .devices() as ? [AVCaptureDevice ] else { return }guard let device = devices.filter ({ $0 .position == .front }).first else { return }guard let input = try ? AVCaptureDeviceInput (device: device) else { return }self .videoInput = inputlet output = AVCaptureVideoDataOutput ()let queue = DispatchQueue .global()output.setSampleBufferDelegate(self , queue: queue) self .videoOutput = output
设置音频的输入源与输出源1 2 3 4 5 6 7 8 9 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()output.setSampleBufferDelegate(self , queue: queue)
添加音频与视频的输入与输出到session中,但是每次添加之前需要先判断是否可以添加
1 2 3 4 5 6 7 8 9 10 11 12 session.beginConfiguration() if session.canAddInput(input) { session.addInput(input) } if session.canAddOutput(output) { session.addOutput(output) } session.commitConfiguration()
二、实现音视频的采集代理 音视频虽然需要遵守的代理名称不一样,但是需要实现的方法是一致的,所以要拿到音频或者视频就得先进行判断,需要用到AVCaptureOutput的这个方法
1 2 3 4 5 // 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!
1 2 3 4 5 6 7 8 9 extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate , AVCaptureAudioDataOutputSampleBufferDelegate { func captureOutput (_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { if videoOutput?.connection(withMediaType: AVMediaTypeVideo ) == connection { print ("视频数据" ) } else { print ("音频数据" ) } } }
三、初始化一个预览图层用来显示采集到的视频(非采集所必须的步骤) 1 2 3 4 5 6 7 guard let previewLayer = AVCaptureVideoPreviewLayer (session: session) else {return }previewLayer.frame = view.bounds view.layer.insertSublayer(previewLayer, at: 0 ) self .previewLayer = previewLayer
现在基本功能都有了,如果想要开始采集音视频只需要调用
1 2 3 4 session.startRunning() session.stopRunning()
切换镜头 其实就是换掉当前的视频输入法制,这里的过程跟上面的设置输入源一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 guard let videoInput = videoInput else { return }let position: AVCaptureDevicePosition = videoInput.device.position == .front ? .back : .frontguard 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 }session.beginConfiguration() session.removeInput(videoInput) if session.canAddInput(newInput) { session.addInput(newInput) } session.commitConfiguration() self .videoInput = newInput
录制视频写入文件 1 fileprivate var movieOutput: AVCaptureMovieFileOutput?
在开始采集音视频的时候就要开始写入文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let fileOutput = AVCaptureMovieFileOutput ()self .movieOutput = fileOutput let connection = fileOutput.connection(withMediaType: AVMediaTypeVideo )connection?.automaticallyAdjustsVideoMirroring = true if session.canAddOutput(fileOutput) { session.addOutput(fileOutput) } let filePath = NSSearchPathForDirectoriesInDomains (.documentDirectory, .userDomainMask, true ).first! + "/abc.mp4" let fileUrl = URL (fileURLWithPath: filePath)fileOutput.startRecording(toOutputFileURL: fileUrl, recordingDelegate: self )
在停止采集音视频的时候停止写入文件
1 2 // 停止写入文件 movieOutput?.stopRecording()
详情请看 DEMO