前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「音视频直播技术」iOS视频采集

「音视频直播技术」iOS视频采集

作者头像
音视频_李超
发布2020-04-02 10:55:11
1.5K0
发布2020-04-02 10:55:11
举报

前言

前两天给大家介绍了如何在iOS下进行音频采集,今天介绍一下在iOS下进行视频采集。要了解iOS是怎样进行视频采集的,首先我们要了解 AVCaptureSession, AVCaptureDevice等几个基本概念及iOS上视频采集的工作原理。

基本概念

iPhone包括了摄像头,麦克风等设备,我们用 AVCaptureDevice 代表它们。同时,摄像头又是一个输入设备,我们还可以用AVCaptureDeviceInput 表式它;同样,麦克风则是另一个输入设备(AVCaptureDeviceInput)。

为了方便,iOS定义了AVCaptureSession类来管理这些输入设备,可以通过 AVCaptureSession 打开某个输入设备进行数据采集,或关闭某个输入设备。

当数据被采集回来后,需要把这些数据进行保存,处理,于是iOS又定义了AVCatpureOutput来做这件事。

下面我们分别介绍每个类。

AVCaptureSession

AVCaptureSession对象用于管理采集活动,协调数据的流入流出。

AVCaptureSession对象的 startRunning() 方法是一个阻塞调用,可能需要一些时间,因此您应该在串行队列上执行会话设置,以使主队列不被阻止(这将保持UI响应)

AVCaptureDevice

AVCaptureDevice对象代表了一个物理设备及与设备相关的属性。你可以使用它设置底层硬件的属性。一个采集设备还可以为 AVCaptureSession 对象提供数据。

可以使有 AVCaptureDevice 的类方法枚举所有有效的设备,并查询它们的能力。当设备有效或无效时,AVCaptureDevice会得到系统的通知。

设置设备属性时,必须首先使用lockForConfiguration()方法将设备锁住。为设备设置完属性后,你应该查询是否已经设置成功,并在设置完成后调用 unlockForConfiguration() 释放锁。

对于大部分属性配置都可以通过 AVCaptureSession 对象来设置,但一些特殊的选项如高帧率,则需要直接在 AVCaptureDevice 上进行设置。

AVCaptureDeviceInput

AVCaptureDeviceInput 是采集设备中的输入端,它继承自 AVCaptureInput,AVCaptureInput是一个抽象类。

AVCaptureConnection

AVCaptureConnection 代表的是 AVCaptureSession 里 AVCaptureInput 与 AVCaptureOutput 对象之间建立的连接。

AVCaptureOutput

AVCaptureOutput 是一个抽象类,有很多具体的实现类,如AVCaptureVideoDataOutput、AVCaptureMovieFileOutput等。如下图所示。但今天我们主要介绍的是 AVCaptureVideoDataOutput。

AVCaptureVideoDataOutput

AVCaptureVideoDataOutput是录制视频和访问视频帧的输出。它继承自 AVCaptureOutput。

下图是AVCaptureDeviceInput、AVCaptureConnection及AVCaptureOutput关系图:

采集视频的步骤

  1. 创建并初始化 AVCaptureSession。
  2. 创建并初始化 AVCaptureVideoDataOutput。
  3. 设置 AVCaptureVideoDataOutput的videoSettings,videoSettings 中的 Key and value 包含了输出图像与视频格式定义。
  4. 调用 AVCaptureVideoDataOutput 对象的 setSampleBufferDelegate 方法,设置采样数据缓冲区的代理。这样当从输入设备采集到数据后,系统就会自动调用AVCaptureVideoDataOutputSampleBufferDelegate 协议中的 captureOutput 方法,从而获取到视频数据。
  5. 将 AVCaptureVideoDataOutput 对象添加到 AVCaptureSession对象中。
  6. 根据视频类型 AVMediaTypeVideo,创建 AVCaptureDevice 对象。(可以创建视频设备也可以创建音频设备)。
  7. 以 AVCaptureDevice 为参数,创建 AVCaptureDeviceInput 对象。
  8. 将 AVCaptureDeviceInput 对像添加到 AVCaptureSession 对象中。
  9. 调用 AVCaptureSession 对象的 setSessionPreset 方法进行属性设置。如 设置 quality level, bitrate, 或其它 output 的 settings。
  10. 调用 Output 对象的 connectionWithMediaType 方法,建立 Input与Output之前的连接。
  11. 调用 AVCaptureSession 对象的 startRunning() 方法,开始视频采集。
  12. 调用 AVCaptureSession 对像的 stopRunning() 方法,停止视频采集。

看看WebRTC是如何做的

在 WebRTC 的 modules/video_capture/objc/rtc_video_capture_objc.mm 文件中实现了iOS视频采集相关的工作:

  • 初始化
代码语言:javascript
复制
......
    
_captureSession = [[AVCaptureSession alloc] init];

......
    
// create and configure a new output (using callbacks)
AVCaptureVideoDataOutput* captureOutput =
    [[AVCaptureVideoDataOutput alloc] init];
    
......

NSDictionary* videoSettings =
    [NSDictionary dictionaryWithObject:val forKey:key];
captureOutput.videoSettings = videoSettings;

// 向 Session 添加输出
if ([_captureSession canAddOutput:captureOutput]) {
    [_captureSession addOutput:captureOutput];
} else {
    ......
}

......
  • 设置捕获设备
代码语言:javascript
复制
......

//获得设备
AVCaptureDevice* captureDevice =
    [DeviceInfoIosObjC captureDeviceForUniqueId:uniqueId];

......

//获得输入设置
AVCaptureDeviceInput* newCaptureInput =
    [AVCaptureDeviceInput deviceInputWithDevice:captureDevice
                                        error:&deviceError];

......

// 偿试向 Session 添加新设备
[_captureSession beginConfiguration];

if ([_captureSession canAddInput:newCaptureInput]) {
    [_captureSession addInput:newCaptureInput];
    addedCaptureInput = YES;
} else {
    addedCaptureInput = NO;
}

[_captureSession commitConfiguration];

......
  • 开始采集数据
代码语言:javascript
复制
......

NSString* captureQuality =
    [NSString stringWithString:AVCaptureSessionPresetLow];
    
if (_capability.width >= 1280 || _capability.height >= 720) {
    captureQuality = [NSString stringWithString:
        AVCaptureSessionPreset1280x720];
} else if (_capability.width >= 640 || _capability.height >= 480) {
    captureQuality = [NSString stringWithString:
        AVCaptureSessionPreset640x480];
} else if (_capability.width >= 352 || _capability.height >= 288) {
    captureQuality = [NSString stringWithString:
        AVCaptureSessionPreset352x288];
}

[_captureSession beginConfiguration];

// picture resolution
[_captureSession setSessionPreset:captureQuality];

_connection = [currentOutput connectionWithMediaType:AVMediaTypeVideo];
[self setRelativeVideoOrientation];

[_captureSession commitConfiguration];

[_captureSession startRunning];
  
......

小结

我们首先介绍了在iOS进行视频采集的一些基础概念,然后又通过分析 WebRTC 代码了解了视频采集的基本步骤(共 12 步)。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 基本概念
    • AVCaptureSession
      • AVCaptureDevice
        • AVCaptureDeviceInput
          • AVCaptureConnection
            • AVCaptureOutput
              • AVCaptureVideoDataOutput
              • 采集视频的步骤
              • 看看WebRTC是如何做的
              • 小结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档