您的位置:首页 > 产品设计 > UI/UE

AVFoundation Programming Guide 之 Media Capture

2014-10-10 17:48 363 查看
AVFoundation框架可以用来自定义相机,看了别人的代码,有很多的不明白,看了文档,就大致翻译下吧,怕以后忘记!

https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW2

Media Capture

从相机or麦克风获取信息,至少需要以下几个类:

1.一个 AVCaptureDevice 的实例,来代表输入的设备,例如:相机or麦克风

2.一个 AVCaptureInput 具体子类的实例,来配置输入设备的端口。

3.一个 AVCaptureOutput 具体子类的实例,来管理到movie 文件or静态图片的输出。

4.一个 AVCaptureSession 的实例,来协调从输入到输出的数据流。

为了向用户展示相机正在录取的图形图像,可能会用到AVCaptureVideoPreviewLayer(CALayer的子类)

通过一个单独的session,可以来配置多个输入输出,如下展示:



然而,对于某些操作,还有考虑输入设备的各种端口是怎样表示的 和 这些端口是怎样连接到输出的。

在capture session中,capture input 和 capture output 之间的联系,是用 AVCaptureConnection 对象表示的。Capture inputs(AVCaptureInput的实例)拥有一个或者多个输入端口(AVCaptureInputPort的实例)。Capture outputs(AVCaptureOutput的实例)能接收一个或多个来源的数据(例如,AVCaptureMovieFileOutput
对象既能接收视频也能接收音频)。

当把一个input 或者 一个output 加入到一个session中时,session就在所有相符的 inputs 端口 和 output之间,建立连接。



可以是用capture connection 来建立或者取消 一个input or output 的数据流。

注意:在iOS设备中,Media capture 不支持同时捕捉前置摄像头和后置摄像头。

使用Capture Session 来协调数据流

AVCaptureSession 是用来管理数据流的中心协调对象。使用此对象的实例来协调AV inputs 到 outputs的输出。把你想要的capture设备和输出加入到session中,用 startRunning 来开始数据流,用 stopRunning 来停止数据流。

AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Add inputs and outputs.
[session startRunning];


配置Session

你可以使用session的preset来指定图像的质量和分辨率。preset是一个常量,指定可能配置中某一个,在某些情况下,特定于设备的实际配置:



如果你想设置媒体的frame size,你应该检查它是否支持此种设置,如下:

if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
session.sessionPreset = AVCaptureSessionPreset1280x720;
}
else {
// Handle the failure.
}


如果你需要更精确的调整session参数 or 在session运行时做出调整,那么你就需要在 beginConfiguration 和 commitConfiguration 方法之间来调整。beginConfiguration 和 commitConfiguration方法确保设备作为一个群体变化, 减少可见性或不一致的状态。在调用 beginConfiguration
之后,你可以增加 or 移除 outputs,改变 sessionPreset 属性的值 ,或者配置个人capture输入或输出属性。只有在你调用了commitConfiguration方法后,这些改变才真正的起作用:

[session beginConfiguration];
// Remove an existing capture device.
// Add a new capture device.
// Reset the preset.
[session commitConfiguration];


监视Capture Session的状态

当Capture Session 开始或者停止,或者中断,capture session会发送通知。如果一个运行时错误发生,你将会收到AVCaptureSessionRuntimeErrorNotification 的通知。你可以通过查询session的running 属性来判断它是否在运行,通过 interrupted 属性来判断是否被中断。此外,running 和 interrupted 属性都是符号KVO的,并且通知都是在主线程中发送的。

AVCaptureDevice 代表Input设备

AVCaptureDevice 抽象表示一个可以提供input 数据(例如视频和音频)给AVCaptureSession对象的物理capture设备。例如,两个视频:一个前置摄像头,一个后置摄像头,一个音频:麦克风。

可以使用 AVCaptureDevice 的类方法 devices 和 devicesWithMediaType: 来找出当前可以使用的 capture设备。可使用的设备也可能会改变,你应该注册来接收 AVCaptureDeviceWasConnectedNotification 和 AVCaptureDeviceWasDisconnectedNotification 的通知。

设备的特性

使用hasMediaType: 来测试设备是否提供了特定的媒体类型,使用supportsAVCaptureSessionPreset: 来测试设备是否支持给定的capture session的预设值。为了给使用者提供信息,你可以得到capture 设备的位置(前面or后面),以及它们的名称。这在你提供一个capture列表给用户选择的时候,可能会有用。

下图显示了前置(AVCaptureDevicePositionFront)和后置(AVCaptureDevicePositionBack)摄像头的位置。



下面的代码示例,遍历所有可用的设备,输出它们的名字,对于视频设备还输出它们的位置:

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");
}
}
}


另外,你还可以得到设备的 model ID 和 unique ID。

Capture设备设置

不同的设备有不同的功能,例如,有些支持不同的 focus or flash 模式......

下面的代码片段,展示了怎样去发现一个视频输入设备有手电筒模式,并且支持给定的capture session 预设值:

NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSMutableArray *torchDevices = [[NSMutableArray alloc] init];

for (AVCaptureDevice *device in devices) {
[if ([device hasTorch] &&
[device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
[torchDevices addObject:device];
}
}


使用Capture Inputs 加入Capture Device 到Session

为了把一个capture设备加入到capture session中,可以使用 AVCaptureDeviceInput 的一个实例(抽象类AVCaptureInput的具体类)。capture input 设备管理设备的端口:

NSError *error;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
}


使用addInput: 把inputs 加入到session中。如果合适,你可以使用 canAddInput: 检查是否兼容现有的session。

AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureDeviceInput *captureDeviceInput = <#Get a capture device input#>;
if ([captureSession canAddInput:captureDeviceInput]) {
[captureSession addInput:captureDeviceInput];
}
else {
// Handle the failure.
}
一个AVCaptureInput 提供一个或者多个流媒体数据。例如,input设备既能提供音频数据也能提供视频数据。input提供的每一个媒体流用AVCaptureInputPort 对象表示。一个capture session使用AVCaptureConnection对象来决定一系列AVCaptureInputPort 和 当个AVCaptureOutput 之间的映射。

使用Capture Outputs 从 Session 处得到Output

要想从capture session处获得output,需添加一个或多个outputs。output是AVCaptureOutput具体子类。如下:

AVCaptureMovieFileOutput to output to a movie file

AVCaptureVideoDataOutput

AVCaptureAudioDataOutput

AVCaptureStillImageOutput
用addOutput:方法把output加入到capture session中,使用canAddOutput:方法来检查capture output是否与存在的session兼容。可以在session正在运行的时候,来增加或者移除outputs:

AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureMovieFileOutput *movieOutput = <#Create and configure a movie output#>;
if ([captureSession canAddOutput:movieOutput]) {
[captureSession addOutput:movieOutput];
}
else {
// Handle the failure.
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AVCaptureSession