采集步骤
- 导入框架
- 相关API主要在AVFoundation框架中,因此需要先导入框架
- 创建捕捉会话(AVCaptureSession)
- 该会话用于连接之后的输入源&输出源
- 输入源:摄像头&话筒
- 输出源:拿到对应的音频&视频数据的出口
- 会话:用于将输入源&输出源连接起来
//1.创建捕捉会话
let session = AVCaptureSession.init()
- 设置视频输入源&输出源
- 输入源(AVCaptureDeviceInput):从摄像头输入
- 输出源(AVCaptureVideoDataOutput):可以设置代理,在代理方法中拿到数据
- 将输入&输出添加到会话中
//2.设置视频输入输出
//2.1 捕获所有的设备(包括前置和后置摄像头)
let videoDevices = AVCaptureDevice.devices(for: .video)
//2.2取出获取后置摄像头
let backDevice = videoDevices.filter { (aVCaptureDevice) -> Bool in
return (aVCaptureDevice.position == .back)
}.first
//2.3创建输入设备
do{
let videoInput = try AVCaptureDeviceInput.init(device: backDevice!)
//添加输入源
if session.canAddInput(videoInput) {
session.addInput(videoInput)
}
}catch{
}
//3 创建视频输出源
//3.1 创建视频输出源
let videoOutput = AVCaptureVideoDataOutput.init()
//3.2 设置代理
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global())
//3.3 添加输出源
if session.canAddOutput(videoOutput) {
session.addOutput(videoOutput)
}
//3.4 创建连接
videoConnectiono = videoOutput.connection(with: .video)
//4 设置音频输入输出
//4.1 创建音频输入
let audioDevices = AVCaptureDevice.devices(for: .audio).first
do{
let audioInput = try AVCaptureDeviceInput.init(device: audioDevices!)
//添加到会话中
if session.canAddInput(audioInput) {
session.addInput(audioInput)
}
}catch{}
//4.2创建音频输出
let audioOutput = AVCaptureVideoDataOutput.init()
audioOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global())
//4.3 添加到会话中
if session.canAddOutput(audioOutput) {
session.addOutput(audioOutput)
}
//4.4 创建连接
audioConnectiono = videoOutput.connection(with: .audio)
- 添加预览图层
- 如果希望用户看到采集的画面,可以添加预览图层
- 该预览图层不是必须的,及时没有添加也可以正常采集数据
//5 添加预览图层
//5.1 创建预览图层
let previewLayer = AVCaptureVideoPreviewLayer.init(session: session)
//5.2 设置图层属性
previewLayer.frame = view.bounds
//5.3 将图层添加到view中
view.layer.insertSublayer(previewLayer, at: 0)
- 开始采集
- 调用会话(AVCaptureSession)的startRunning方法即可开始采集
//6 开始采集
session.startRunning()
extension ViewController:AVCaptureVideoDataOutputSampleBufferDelegate{
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if connection == videoConnectiono{
print("视频数据")
}else{
print("音频数据")
}
}
}
停止扫描
- 比如用户不再直接,我们需要停止扫描
- 移除预览图层(不再直播肯定不需要预览图层了)
- 停止扫描(调用session的stopRunning方法)
- 将session设置为nil(对象不再使用,指针置空)
// 1.移除图层
previewLayer?.removeFromSuperlayer()
// 2.停止扫描
session?.stopRunning()
// 3.将对象重置为nil
session = nil