WebRTC Native 源码导读(七):iOS 相机采集实现分析

从上一篇开始,我们这个系列就进入了 iOS 的世界,接下来我打算先熟悉一下 iOS 相机相关的内容,包括采集、预览、编码等,本篇重点是采集。

WebRTC-iOS 的相机采集主要涉及到以下几个类:AVCaptureSession, RTCCameraVideoCapturer, RTCVideoFrame。

AVCaptureSession 是 iOS 和 macOS 系统提供的采集管理类,位于 AVFoundation.framework 中,在 RTCCameraVideoCapturer 中完成了对 AVCaptureSession 的使用,RTCVideoFrame 则是对视频数据的封装。

AVCaptureSession

我们先来了解一下 AVCaptureSession 的基本使用。

一个 session 需要有 input 和 output,这样数据才能在其中流动(处理),下面这个 session 包含了音视频输入,预览、图片、视频输出:

AVCaptureSession 的使用主要分为以下几步:

  • 创建 session;
  • 配置 session:添加 input 和 output device;
  • 启停 session;

创建 session

创建 session 很简单,就是构造一个对象即可:

session = [[AVCaptureSession alloc] init];

配置 session

由于配置 session 是多步操作,为了保证原子性,AVCaptureSession 提供了事务机制,即先 beginConfiguration,再添加 device,最后 commitConfiguration

// 开始配置
[session beginConfiguration];

// 设置采集参数 preset
session.sessionPreset = AVCaptureSessionPresetHigh;

// 选择后置广角相机 AVCaptureDeviceTypeBuiltInWideAngleCamera
// 新款 iPhone 可以选择双摄相机 AVCaptureDeviceTypeBuiltInDualCamera
AVCaptureDevice* videoDevice = [AVCaptureDevice
    defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera
                        mediaType:AVMediaTypeVideo
                        position:AVCaptureDevicePositionBack];

// 创建 video input device
AVCaptureDeviceInput* videoDeviceInput =
    [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if ([session canAddInput:videoDeviceInput]) {
    // 添加 video input device
    [session addInput:videoDeviceInput];
}

// 选择音频设备
AVCaptureDevice* audioDevice =
    [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

// 创建 audio input device
AVCaptureDeviceInput* audioDeviceInput =
    [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];

if ([session canAddInput:audioDeviceInput]) {
    // 添加 audio input device
    [session addInput:audioDeviceInput];
}

// 创建视频录制
AVCaptureMovieFileOutput* movieFileOutput =
    [[AVCaptureMovieFileOutput alloc] init];

if ([session canAddOutput:movieFileOutput]) {
    // 添加视频录制
    [session addOutput:movieFileOutput];
    AVCaptureConnection* connection =
        [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
    if (connection.isVideoStabilizationSupported) {
        connection.preferredVideoStabilizationMode =
            AVCaptureVideoStabilizationModeAuto;
    }
}

// 提交配置
[session commitConfiguration];

启停 session

启停 session 也比较简单,就是一个接口的调用:

``` objective-c
// 启动 session
[session startRunning];

// 停止 session
[session stopRunning];

top Created with Sketch.