采集步驟
- 導(dǎo)入框架
- 相關(guān)API主要在AVFoundation框架中,因此需要先導(dǎo)入框架
- 創(chuàng)建捕捉會(huì)話(AVCaptureSession)
- 該會(huì)話用于連接之后的輸入源&輸出源
- 輸入源:攝像頭&話筒
- 輸出源:拿到對(duì)應(yīng)的音頻&視頻數(shù)據(jù)的出口
- 會(huì)話:用于將輸入源&輸出源連接起來
//1.創(chuàng)建捕捉會(huì)話
let session = AVCaptureSession.init()
- 設(shè)置視頻輸入源&輸出源
- 輸入源(AVCaptureDeviceInput):從攝像頭輸入
- 輸出源(AVCaptureVideoDataOutput):可以設(shè)置代理,在代理方法中拿到數(shù)據(jù)
- 將輸入&輸出添加到會(huì)話中
//2.設(shè)置視頻輸入輸出
//2.1 捕獲所有的設(shè)備(包括前置和后置攝像頭)
let videoDevices = AVCaptureDevice.devices(for: .video)
//2.2取出獲取后置攝像頭
let backDevice = videoDevices.filter { (aVCaptureDevice) -> Bool in
return (aVCaptureDevice.position == .back)
}.first
//2.3創(chuàng)建輸入設(shè)備
do{
let videoInput = try AVCaptureDeviceInput.init(device: backDevice!)
//添加輸入源
if session.canAddInput(videoInput) {
session.addInput(videoInput)
}
}catch{
}
//3 創(chuàng)建視頻輸出源
//3.1 創(chuàng)建視頻輸出源
let videoOutput = AVCaptureVideoDataOutput.init()
//3.2 設(shè)置代理
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global())
//3.3 添加輸出源
if session.canAddOutput(videoOutput) {
session.addOutput(videoOutput)
}
//3.4 創(chuàng)建連接
videoConnectiono = videoOutput.connection(with: .video)
//4 設(shè)置音頻輸入輸出
//4.1 創(chuàng)建音頻輸入
let audioDevices = AVCaptureDevice.devices(for: .audio).first
do{
let audioInput = try AVCaptureDeviceInput.init(device: audioDevices!)
//添加到會(huì)話中
if session.canAddInput(audioInput) {
session.addInput(audioInput)
}
}catch{}
//4.2創(chuàng)建音頻輸出
let audioOutput = AVCaptureVideoDataOutput.init()
audioOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global())
//4.3 添加到會(huì)話中
if session.canAddOutput(audioOutput) {
session.addOutput(audioOutput)
}
//4.4 創(chuàng)建連接
audioConnectiono = videoOutput.connection(with: .audio)
- 添加預(yù)覽圖層
- 如果希望用戶看到采集的畫面,可以添加預(yù)覽圖層
- 該預(yù)覽圖層不是必須的,及時(shí)沒有添加也可以正常采集數(shù)據(jù)
//5 添加預(yù)覽圖層
//5.1 創(chuàng)建預(yù)覽圖層
let previewLayer = AVCaptureVideoPreviewLayer.init(session: session)
//5.2 設(shè)置圖層屬性
previewLayer.frame = view.bounds
//5.3 將圖層添加到view中
view.layer.insertSublayer(previewLayer, at: 0)
- 開始采集
- 調(diào)用會(huì)話(AVCaptureSession)的startRunning方法即可開始采集
//6 開始采集
session.startRunning()
- 遵守協(xié)議,實(shí)現(xiàn)代理方法
extension ViewController:AVCaptureVideoDataOutputSampleBufferDelegate{
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if connection == videoConnectiono{
print("視頻數(shù)據(jù)")
}else{
print("音頻數(shù)據(jù)")
}
}
}
停止掃描
- 比如用戶不再直接,我們需要停止掃描
- 移除預(yù)覽圖層(不再直播肯定不需要預(yù)覽圖層了)
- 停止掃描(調(diào)用session的stopRunning方法)
- 將session設(shè)置為nil(對(duì)象不再使用,指針置空)
// 1.移除圖層
previewLayer?.removeFromSuperlayer()
// 2.停止掃描
session?.stopRunning()
// 3.將對(duì)象重置為nil
session = nil