iOS直播(一)AVFoundation音视频采集

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

一、要实现从摄像头和麦克风获取视频和音频,需要使用苹果提供的AVFoundation框架,下面是需要用到的类的说明:

1.AVCaptureSession

AV Foundation捕捉栈的核心类是AVCaptureSession。一个AVCaptureSession相当于一个虚拟的“插线板”,用以连接输入和输出的资源。

2.AVCaptureDevice

AVCaptureDevice为诸如摄像头或麦克风等物理设备定义了一个接口,针对物理设备定义了大量的控制方法,比如控制摄像头的对焦、曝光、白平衡和闪光灯等。

3.AVCaptureDeviceInput

在使用捕捉设备进行处理前,首先需要将它添加为捕捉会话的输入。但是需要将它封装在一个AVCaptureDeviceInput实例中,这个对象在设备输出数据和捕捉会话间扮演接线板的作用。

4.AVCaptureOutput

AVCaptureOutput是一个抽象基类,用于为从捕捉会话得到的数据寻找输出目的地。

5.AVCaptureConnection

捕捉会话首先需要确定由给定捕捉设备输入渲染的媒体类型,并自动建立其到能够接收该媒体类型的捕捉输出端的连接。可以让开发者对信号流进行底层的控制。比如禁用某些特定的连接,或在音频连接中访问单独的音频轨道。

6.AVCaptureVideoPreviewLayer

预览层是一个Core Animation的CALayer子类,对捕捉视频数据进行实时预览。

二、示例代码

1.将整个过程拆分为视频采集、音频采集、预览三步实现:

    override func viewDidLoad() {
        super.viewDidLoad()
        //1.初始化视频的输入&输出
        setUpVideoInputOutput()

        //2.初始化音频的输入&输出
        setupAudioInputOutput()

        //3.初始化一个预览图层
        setupPreviewLayer()

    }

2.视频采集

    fileprivate func setUpVideoInputOutput() {
        //1.获取视频输入设备列表
        guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else {return}
        //2.获取视频输入设备(前置摄像头)
        guard let device = devices.filter({$0.position == .front}).first else {return}
        //3.创建输入
        guard let input = try? AVCaptureDeviceInput(device: device) else {return}
        self.videoInput = input

        //2.添加视频输出
        let output = AVCaptureVideoDataOutput()
        let queue = DispatchQueue.global()
        output.setSampleBufferDelegate(self, queue: queue)
        self.videoOutput = output

        //3.添加输入&输出
        addInputOutputToSession(input, output)
    }

3.音频采集

    fileprivate func setupAudioInputOutput() {
        //1.获取麦克风输入设备
        guard let device = AVCaptureDevice.default(for: .audio) else { return }
        //2.创建输入
        guard let input = try? AVCaptureDeviceInput(device: device) else { return }

        //2.创建输出
        let output = AVCaptureAudioDataOutput()
        let queue = DispatchQueue.global()
        output.setSampleBufferDelegate(self, queue: queue)

        //3.添加输入&输出
        addInputOutputToSession(input, output)
    }

4.音视频添加输入&输出的公用方法(2、3步中的addInputOutputToSession方法)

    private func addInputOutputToSession(_ input : AVCaptureInput, _ output : AVCaptureOutput){
        session.beginConfiguration()
        //将输入连接到session
        if session.canAddInput(input) {
            session.addInput(input)
        }
        //将输出连接到session
        if session.canAddOutput(output) {
            session.addOutput(output)
        }
        session.commitConfiguration()
    }

5.实现2、3步中的SampleBufferDelegate代理方法(采集到音视频时的回调方法)

extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        if videoOutput?.connection(with: .video) == connection {
            print("采集视频")
        }else{
            print("采集音频")
        }
    }
}

6.创建预览层

    fileprivate func setupPreviewLayer() {
        //1.创建预览图层
        let previewLayer = AVCaptureVideoPreviewLayer(session: session)

        //2.设置previewLayer属性
        previewLayer.frame = view.bounds;

        //3.将图层添加到控制器的view的layer中
        view.layer.insertSublayer(previewLayer, at: 0)
        self.previewLayer = previewLayer
    }

完整demo代码:
https://github.com/dolacmeng/VideoCaptureDemo

猜你喜欢

转载自blog.csdn.net/dolacmeng/article/details/81268622