iOS直播一AVFoundation音视频采集
目录
iOS直播(一)AVFoundation音视频采集
一、要实现从摄像头和麦克风获取视频和音频,需要使用苹果提供的AVFoundation框架,下面是需要用到的类的说明:
1.AVCaptureSession
AV Foundation捕捉栈的核心类是AVCaptureSession。一个AVCaptureSession相当于一个虚拟的“插线板”,用以连接输入和输出的资源。
2.AVCaptureDevice
AVCaptureDevice为诸如摄像头或麦克风等物理设备定义了一个接口,针对物理设备定义了大量的控制方法,比如控制摄像头的对焦、曝光、白平衡和闪光灯等。
3.AVCaptureDeviceInput
在使用捕捉设备进行处理前,首先需要将它添加为捕捉会话的输入。但是需要将它封装在一个AVCaptureDeviceInput实例中,这个对象在设备输出数据和捕捉会话间扮演接线板的作用。
4.AVCaptureOutput
AVCaptureOutput是一个抽象基类,用于为从捕捉会话得到的数据寻找输出目的地。
5.AVCaptureConnection
捕捉会话首先需要确定由给定捕捉设备输入渲染的媒体类型,并自动建立其到能够接收该媒体类型的捕捉输出端的连接。可以让开发者对信号流进行底层的控制。比如禁用某些特定的连接,或在音频连接中访问单独的音频轨道。
6.AVCaptureVideoPreviewLayer
预览层是一个Core Animation的CALayer子类,对捕捉视频数据进行实时预览。
二、示例代码
1.将整个过程拆分为视频采集、音频采集、预览三步实现:
override func viewDidLoad() {
super.viewDidLoad()
//1.初始化视频的输入&输出
setUpVideoInputOutput()
//2.初始化音频的输入&输出
setupAudioInputOutput()
//3.初始化一个预览图层
setupPreviewLayer()
}
2.视频采集
fileprivate func setUpVideoInputOutput() {
//1.获取视频输入设备列表
guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else {return}
//2.获取视频输入设备(前置摄像头)
guard let device = devices.filter({$0.position == .front}).first else {return}
//3.创建输入
guard let input = try? AVCaptureDeviceInput(device: device) else {return}
self.videoInput = input
//2.添加视频输出
let output = AVCaptureVideoDataOutput()
let queue = DispatchQueue.global()
output.setSampleBufferDelegate(self, queue: queue)
self.videoOutput = output
//3.添加输入&输出
addInputOutputToSession(input, output)
}
3.音频采集
fileprivate func setupAudioInputOutput() {
//1.获取麦克风输入设备
guard let device = AVCaptureDevice.default(for: .audio) else { return }
//2.创建输入
guard let input = try? AVCaptureDeviceInput(device: device) else { return }
//2.创建输出
let output = AVCaptureAudioDataOutput()
let queue = DispatchQueue.global()
output.setSampleBufferDelegate(self, queue: queue)
//3.添加输入&输出
addInputOutputToSession(input, output)
}
4.音视频添加输入&输出的公用方法(2、3步中的addInputOutputToSession方法)
private func addInputOutputToSession(_ input : AVCaptureInput, _ output : AVCaptureOutput){
session.beginConfiguration()
//将输入连接到session
if session.canAddInput(input) {
session.addInput(input)
}
//将输出连接到session
if session.canAddOutput(output) {
session.addOutput(output)
}
session.commitConfiguration()
}
5.实现2、3步中的SampleBufferDelegate代理方法(采集到音视频时的回调方法)
extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate{
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if videoOutput?.connection(with: .video) == connection {
print("采集视频")
}else{
print("采集音频")
}
}
}
6.创建预览层
fileprivate func setupPreviewLayer() {
//1.创建预览图层
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
//2.设置previewLayer属性
previewLayer.frame = view.bounds;
//3.将图层添加到控制器的view的layer中
view.layer.insertSublayer(previewLayer, at: 0)
self.previewLayer = previewLayer
}
完整demo代码: