静态和视频媒体捕获
去管理来自摄像头或麦克风的捕获,你需要装配对象去代表输入和输出,使用一个 AVCaptureSession 去协调输入和输出。
-
AVCaptureDevice : 实例对象代表一个输入设备。例如照相机和麦克风
-
AVCaptureOutput : 子类的具体实例对象,输入设备的配置端口
- AVCaptureMovieFileOutput : 输出一个电影文件
- AVCaptureVideoDataOutput : 加工视频数据
- AVCaptureAudioDataOutput : 加工音频数据
- AVCaptureStillImageOutput : 从源数据中捕获静态图片
-
AVCaptureOutput : 子类的具体实例对象,管理输出到电影文件或者静态图片。
-
AVCaptureSession : 协调输入和输出之间的数据流
你可以使用 AVCaptureVideoPreviewLayer 来展示摄像头正在记录的预览。
可以在一个 session 中配置多个输入和输出
![](https://img.haomeiwen.com/i446092/586e828eafacb2af.png)
在一个捕获 session 中,使用 AVCaptureConnection 实例来代表 input 和 output 之间的连接。捕获输入有一个或多个输入端口,捕获输出能够接受来自一个或多个源的数据。
- input : 前置,后置摄像头,麦克风。
- output : 视频, 音频。
对于大多数应用程序,你需要更多的细节。对于更多的操作,无论怎样(例如,你需要去监听音频中的功率级别)你需要去考虑如何表示输入设备的各个端口以及这些端口如何连接到输出。
一个输入和一个输出之间的连接使用一个 AVCaptureConnection 实例来表示。捕获输入有一个或多个输入端口(AVCaptureInputPort 实例对象)。 捕获的输出实例对象 能够接受来自一个或多个源(例如:AVCaptureMovieFileOutput 对象可以接受视频和音频数据)
当你添加输入或输出到 session, 会话将在所有兼容的捕获输入端口和捕获输出之间形成连接,如图所示。 捕获输入和捕获输出之间的连接由 AVCaptureConnection 对象表示。(AVCaptureConnection 对象是自动创建的)
![](https://img.haomeiwen.com/i446092/e5c76c99e6940c3c.png)
可以使用 AVCaptureConnection 对象去启用或者禁用从 input 到 output 的数据流。也可以使用 AVCaptureConnection 对象去监听声道的频率等。
在iOS 上是不支持同时使用前置和后置摄像头进行同步捕获。 模拟器不支持视频捕获
视频音频操作必须是真机
使用 session 去协调数据流
session 是你用来管理捕获数据的中央协调对象。使用 session 去协调 AV 输入设备和输出设备的数据流。你可以添加捕获设备,和输入到你想要的 session。 session 通过发送 startRunning 消息去开启数据流。 通过调用 stopRunning 去停止数据流。
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Add inputs and outputs.
// 没有添加输入设备,和输出。 直接开启时没有意义的。
[session startRunning];
配置 Session
通过一个 session 的 预设 来配置你想要的图片质量和分辨率。
AVCaptureSessionPresetHigh : 高质量
AVCaptureSessionPresetMedium : 中等质量, wifi 分享
AVCaptureSessionPresetLow : 低质量 3g分享
// 高质量,每个设备是不一样的。
// 中等和低质量的实际值可能会发生改变。
AVCaptureSessionPreset640x480 : vga
AVCaptureSessionPreset1280x720 : 720hd
AVCaptureSessionPresetPhoto : video output 是不支持的。
** 在配置的时候要先判断设备是否支持。**
if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
session.sessionPreset = AVCaptureSessionPreset1280x720;
}
else {
// Handle the failure.
}
当你需要对 session 的参数进行比预设更加精细的设置的时候,或者在 session run 的时候进行调整参数。你需要将调整的代码写在 beginConfiguration commitConfiguration 方法之间。
beginConfiguration和commitConfiguration方法确保设备更改作为一个组发生,从而最小化状态的可见性或不一致性。 调用beginConfiguration后,可以添加或删除输出,更改sessionPreset属性或配置单个捕获输入或输出属性。 在您调用commitConfiguration之前,实际上不会进行任何更改,此时它们一起应用。
[session beginConfiguration]; // 加锁
// Remove an existing capture device. (移除一个已经存在的设备)
// Add a new capture device. (添加一个新设备)
// Reset the preset. (重新进行预设操作)
[session commitConfiguration]; // 释放锁
// 调整的设置,在这一句代码过后统一生效
监测捕获会话状态
- 通知: 运行,停止,暂停。错误处理。
- kvo
- 属性: 是否正在运行,或正在暂停。
capture session 发送的通知能够被监听, 当 session 开始运行,停止运行,暂停过程中出现错误。 你能够注册和接受 AVCaptureSessionRuntimeErrorNotification 通知。 也可以通过 session’s running 和 interrupted 属性来判断 session 是否运行和暂停。
** kvo 和通知的处理都在主线程。**
一个 AVCaptureDevice 对象代表一个输入设备
AVCaptureDevice 是一个给 session 提供数据(音频或视频)的抽象的物理设备。每一个设备就是是一个对象,例如,前置摄像头,后置摄像头,麦克风。
你可以用AVCaptureDevice 的 devices 和 devicesWithMediaType: 去获取当前可用的设备。
你可查看Device Capture Settings 来知道 iphone ipad ipod 都提供了那些特性。 可用设备的列表可能会发生改变。当前的输入设备可能变的不可用。(设备被另一些app 占用)。 新的输入设备可能变的可用。(其他app 放弃占用设备)。 你可以注册 AVCaptureDeviceWasConnectedNotification 和 AVCaptureDeviceWasDisconnectedNotification notifications 来获取设备可用和不可用的变化信息。
设备特征
你可以询问设备提供了那些特性。
你也可以测试设备是否提供了某些特性,或是否支持 session 预设的媒体类型。
hasMediaType:
supportsAVCaptureSessionPreset:
获取可用设备
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices) {
NSLog(@"Device name: %@", [device localizedName]);
if ([device hasMediaType:AVMediaTypeVideo]) {
if ([device position] == AVCaptureDevicePositionBack) {
NSLog(@"Device position : back");
}
else {
NSLog(@"Device position : front");
}
}
}
除此之外你还可以通过设备的唯一id 和模式id 来获取。
设备捕捉设置
不同的设备具有不同的能力; 例如,一些可以支持不同的聚焦或闪光模式; 可可能支持自动对焦到某个感兴趣的点。
以下代码片段显示了如何找到具有手电筒模式并支持给定捕获会话预设的视频输入设备:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSMutableArray *torchDevices = [[NSMutableArray alloc] init];
for (AVCaptureDevice *device in devices) {
[if ([device hasTorch] &&
[device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
[torchDevices addObject:device];
}
}
如果您发现符合条件的多个设备,您可以让用户选择他们想要使用的设备。 要向用户显示设备的描述,可以使用其localizedName 属性。
您以类似的方式使用各种不同的功能。 有常数来指定特定的模式,你可以问设备是否支持特定的模式。 在多种情况下,您可以观察属性在要素更改时通知。 在所有情况下,应在更改特定功能的模式之前锁定设备,如配置设备中所述。
聚焦到某个点和曝光到某个点事项目排斥的。聚焦模式和曝光模式也是相互排斥的。
聚焦模式
三个聚焦模式:
- **AVCaptureFocusModeLocked: ** 焦点位置是固定的。当您想要允许用户组合场景然后锁定焦点时,这是有用的。
- **AVCaptureFocusModeAutoFocus: ** 相机执行单次扫描对焦,然后还原到锁定。
这适合于您要选择要对其进行对焦的特定项目,然后保持对该项目的聚焦的情况,即使它不是场景的中心。
- **AVCaptureFocusModeContinuousAutoFocus: ** 相机根据需要连续自动对焦。
你必须使用 isFocusModeSupported: 去确定设备是否支持给定的对焦模式。 使用 focusMode 属性去设置对焦模式。
此外, 设备可能支持聚焦到某个点。 你使用 focusPointOfInterestSupported 去测试是否支持。 如果支持,使用 focusPointOfInterest 来设置焦点。您传递一个CGPoint,其中{0,0}表示图片区域的左上角,{1,1}表示右下角,设备处于横屏模式,home 按键在右侧,即使设备处于竖直模式也是如此 。
您可以使用adjustFocus属性来确定设备当前是否正在对焦。可以使用 kvo 来观察 设备开始和停止对焦。
if ([currentDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
[currentDevice setFocusPointOfInterest:autofocusPoint];
[currentDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}
曝光模式
两个曝光模式:
- **AVCaptureExposureModeContinuousAutoExposure: ** 设备根据需要自动调整曝光
- **AVCaptureExposureModeLocked: ** 曝光水平固定在其当前水平。
你使用 isExposureModeSupported: 方法去确定设备是否支持给定的曝光模式, 使用 exposureMode 设置曝光模式。
此外,设备可能支持曝光到一个点。 通过调用 exposurePointOfInterestSupported 测试是否支持。如果支持,使用 exposurePointOfInterest 来设置这个点。您传递一个CGPoint,其中{0,0}表示图片区域的左上角,{1,1}表示右下角,设备处于横屏模式,home 按键在右侧,即使设备处于竖直模式也是如此 。
您可以使用 adjustingExposure 属性来确定设备当前是否正在对焦。可以使用 kvo 来观察 设备开始和停止对焦。
if ([currentDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
CGPoint exposurePoint = CGPointMake(0.5f, 0.5f);
[currentDevice setExposurePointOfInterest:exposurePoint];
[currentDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}
闪光模式
三种闪光模式:
- **AVCaptureFlashModeOff: ** 闪光关闭
- AVCaptureFlashModeOn: 闪光开启
- AVCaptureFlashModeAuto: 闪光灯将根据环境光条件而闪光。
使用 hasFlash 确定是否有闪光, 在通过 isFlashModeSupported 来确定是否支持给定的闪光模式。 通过 flashMode 来设置闪光模式。
网友评论