Farlanki

使用AVCptureSession

字数统计: 724阅读时长: 2 min
2016/02/29 Share

使用AVCptureSession获取静态图片,我们需要如下这几个类:

  • AVCaptureDevice : 代表输入设备,如照相机或者麦克风.它被用于控制硬件特性,诸如镜头的位置、曝光、闪光灯等。
  • AVCaptureInput : 提供来自设备的数据。
  • AVCaptureOutput : 管理视频文件或者静态图像的输出.以下是三种关于静态图片捕捉的具体子类:
    – AVCaptureStillImageOutput 用于捕捉静态图片
    – AVCaptureMetadataOutput 启用检测人脸和二维码
    – AVCaptureVideoOutput 为实时预览图提供原始帧
  • AVCaptureSession: 协调输入和输出之间的数据流.


在很多情况下,这就是我们所需要的.但是,在一些情况下,我们需要选择哪个输入的端口需要和输出相连接.
一个AVCaptureConnection对象代表了一个输入和输出在session中的连接.输入拥有一个或者多个接口,而输出可以接受一个或者多个来源的数据.
当往session中加入输入和输出,session会生成所有兼容的input和output之间的connection.所以我们需要选择我们需要的connection

设置并获取静态图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//设置
self.session = AVCaptureSession()
self.session?.sessionPreset = AVCaptureSessionPresetPhoto
let DevicesArray = AVCaptureDevice.devices()
for device in DevicesArray {
if(device.position == AVCaptureDevicePosition.Front){
do{
try self.deviceInput = AVCaptureDeviceInput(device: device as! AVCaptureDevice)
//在APP第一次调用时会触发系统提示,向用户请求访问相机.如果拒绝,输入会一直是一个黑色的数据流
}
catch{print("initialize device failed")}
}
}
self.session?.addInput(self.deviceInput)
self.stillImageOutput = AVCaptureStillImageOutput()
let outputSetting = [AVVideoCodecKey : AVVideoCodecJPEG]
self.stillImageOutput?.outputSettings = outputSetting
self.session?.addOutput(self.stillImageOutput)
for connection in (stillImageOutput?.connections)!{
for port in (connection as! AVCaptureConnection).inputPorts{
if (port.mediaType == AVMediaTypeVideo){
self.captureConnection = connection as! AVCaptureConnection
self.captureConnection?.videoOrientation = AVCaptureVideoOrientation.Portrait
break
}
}
}
self.session?.startRunning()
//获取图片
self.stillImageOutput?.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler: { (buffer, error) -> Void in
if(buffer != nil){
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer)
var image = UIImage(data: imageData)
}

录制视频,并写入文件

写入文件有两种方法.

AVCaptureMovieFileOutput

将视频写入文件,最简单的选择就是使用 AVCaptureMovieFileOutput 对象。把它作为输出添加到 capture session 中,就可以将视频和音频写入 QuickTime 文件,这只需很少的配置。

AVCaptureDataOutput 和 AVAssetWriter

重点说说第二种方法.
在session开始后,输出会捕获视频和音频的样本缓存,并且发送到代理.在这之前,需要先设置代理

1
public func setSampleBufferDelegate(sampleBufferDelegate: AVCaptureVideoDataOutputSampleBufferDelegate!, queue sampleBufferCallbackQueue: dispatch_queue_t!)

其中的queue指定了所有采样缓存协议方法的被调用的线程.
这样,在session开始后,会调用代理的方法:

1
2
3
optional func captureOutput(_ captureOutput: AVCaptureOutput!,
didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
fromConnection connection: AVCaptureConnection!)

在这个方法里我们可以对采样缓冲进行处理,或者保持原样传送.可以利用AVAssetWriterInput写入文件.

1
public func appendSampleBuffer(sampleBuffer: CMSampleBuffer) -> Bool

CVPixelBufferRef

对于CVPixelBufferRef,我们需要用到AVAssetWriterInputPixelBufferAdaptor来把buffer附加到AVAssetWriterInput上.

1
2
3
4
public init(assetWriterInput input: AVAssetWriterInput, sourcePixelBufferAttributes: [String : AnyObject]?)

public func appendPixelBuffer(pixelBuffer: CVPixelBuffer, withPresentationTime presentationTime: CMTime) -> Bool
}
CATALOG
  1. 1. 设置并获取静态图片
  2. 2. 录制视频,并写入文件
    1. 2.1. AVCaptureMovieFileOutput
    2. 2.2. AVCaptureDataOutput 和 AVAssetWriter
  3. 3. CVPixelBufferRef