iOS 音视频采集以及写入文件(swift)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/glt_code/article/details/75212524

iOS音视频采集以及写入文件(swift)


注意:配置允许访问相机与麦克风参考这里

1.初始化文件属性
class ViewController: UIViewController {
    
    fileprivate lazy var session: AVCaptureSession = AVCaptureSession()
    //视频输出
    fileprivate var videoOutPut: AVCaptureVideoDataOutput?
    //预览层
    fileprivate var previewLayer: AVCaptureVideoPreviewLayer?
    //视频输入
    fileprivate var videoInput: AVCaptureDeviceInput?
    //文件输出
    fileprivate var fileOutPut: AVCaptureMovieFileOutput?

    override func viewDidLoad() {
        super.viewDidLoad()
        //MARK: 视频采集
        initVideoInputOutput()
        //MARK: 音频采集
        initAudioInputOutput()
        //MARK: 创建预览层
        initPreViewLayer()
    }
    
}


2.音视频进行采集
extension ViewController {
    //视频采集
    fileprivate func initVideoInputOutput(){
        //视频输入
        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 = input
        //视频输出
        let output = AVCaptureVideoDataOutput()
        output.setSampleBufferDelegate(self, queue: DispatchQueue.global())
        self.videoOutPut = output
        //添加输入输出
        addInputOutPut(input, output)
    }
    
    //音频采集
    fileprivate func initAudioInputOutput(){
        //音频输入
        guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else {return}
        guard let input = try? AVCaptureDeviceInput(device: device) else {return}
        //音频输出
        let output = AVCaptureAudioDataOutput()
        output.setSampleBufferDelegate(self, queue: DispatchQueue.global())
        //添加输入输出
        addInputOutPut(input, output)
    }
    
    //添加输入和输出
    private func addInputOutPut(_ input: AVCaptureInput, _ output: AVCaptureOutput) {
        //添加输入输出
        session.beginConfiguration()
        if session.canAddInput(input) {
            session.addInput(input)
        }
        if session.canAddOutput(output){
            session.addOutput(output)
        }
        session.commitConfiguration()
    }
    //创建预览层
    fileprivate func initPreViewLayer(){
        guard let preLayer = AVCaptureVideoPreviewLayer(session: session) else {return}
        self.previewLayer = preLayer
        preLayer.frame = view.bounds
        view.layer.insertSublayer(preLayer, at: 0)
    }
}


3.采集的代理方法
//MARK: AVCapture delegate
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate {
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        if videoOutPut?.connection(withMediaType: AVMediaTypeVideo) == connection {
            print("采集到视频数据")
        }else{
            print("采集到音频数据")
        }
    }
}


4.开始采集、结束采集、切换摄像头方法调用
extension ViewController{

    //开始采集
    @IBAction func startCapture(_ sender: Any) {
        print("startCapture")
        session.startRunning()
        movieOutPutFile()
    }
    
    //结束采集
    @IBAction func endCapture(_ sender: Any) {
        print("endCapture")
        self.fileOutPut?.stopRecording()
        session.stopRunning()
        previewLayer?.removeFromSuperlayer()
    }
    
    //切换镜头
    @IBAction func changeDirection(_ sender: Any) {
        print("changeDirection")
        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}
        self.videoInput = newInput
        session.beginConfiguration()
        session.removeInput(videoInput)
        if session.canAddInput(newInput) {
            session.addInput(newInput)
        }
        session.commitConfiguration()
    }
    
    //写入文件
    fileprivate func movieOutPutFile() {
        let fileOutPut = AVCaptureMovieFileOutput()
        let connection = fileOutPut.connection(withMediaType: AVMediaTypeVideo)
        connection?.automaticallyAdjustsVideoMirroring = true
        print(session)
        session.beginConfiguration()
        session.removeOutput(self.fileOutPut)
        if session.canAddOutput(fileOutPut) {
            session.addOutput(fileOutPut)
        }
        session.commitConfiguration()
        self.fileOutPut = fileOutPut
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/glt.mp4"
        fileOutPut.startRecording(toOutputFileURL: URL(fileURLWithPath: path), recordingDelegate: self)
    }
    
}

5.写入文件代理
//MARK: 写入文件代理
extension ViewController: AVCaptureFileOutputRecordingDelegate {

    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {
        print("开始录制")
    }
    
    func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
        print("结束录制")
    }
    
}



猜你喜欢

转载自blog.csdn.net/glt_code/article/details/75212524