iOS 音視訊採集以及寫入檔案(swift)
阿新 • • 發佈:2019-01-12
iOS音視訊採集以及寫入檔案(swift)
注意:配置允許訪問相機與麥克風參考這裡
1.初始化檔案屬性
class ViewController: UIViewController { fileprivate lazy var session: AVCaptureSession = AVCaptureSession() //視訊輸出 fileprivate var videoOutPut: AVCaptureVideoDataOutput? //預覽層 fileprivate var previewLayer: AVCaptureVideoPreviewLayer? //視訊輸入 fileprivate var videoInput: AVCaptureDeviceInput? //檔案輸出 fileprivate var fileOutPut: AVCaptureMovieFileOutput? override func viewDidLoad() { super.viewDidLoad() //MARK: 視訊採集 initVideoInputOutput() //MARK: 音訊採集 initAudioInputOutput() //MARK: 建立預覽層 initPreViewLayer() } }
2.音視訊進行採集
extension ViewController { //視訊採集 fileprivate func initVideoInputOutput(){ //視訊輸入 guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else{return} guard let device = devices.filter({ $0.position == .front }).first else {return} guard let input = try? AVCaptureDeviceInput(device: device) else {return} self.videoInput = input //視訊輸出 let output = AVCaptureVideoDataOutput() output.setSampleBufferDelegate(self, queue: DispatchQueue.global()) self.videoOutPut = output //新增輸入輸出 addInputOutPut(input, output) } //音訊採集 fileprivate func initAudioInputOutput(){ //音訊輸入 guard let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) else {return} guard let input = try? AVCaptureDeviceInput(device: device) else {return} //音訊輸出 let output = AVCaptureAudioDataOutput() output.setSampleBufferDelegate(self, queue: DispatchQueue.global()) //新增輸入輸出 addInputOutPut(input, output) } //新增輸入和輸出 private func addInputOutPut(_ input: AVCaptureInput, _ output: AVCaptureOutput) { //新增輸入輸出 session.beginConfiguration() if session.canAddInput(input) { session.addInput(input) } if session.canAddOutput(output){ session.addOutput(output) } session.commitConfiguration() } //建立預覽層 fileprivate func initPreViewLayer(){ guard let preLayer = AVCaptureVideoPreviewLayer(session: session) else {return} self.previewLayer = preLayer preLayer.frame = view.bounds view.layer.insertSublayer(preLayer, at: 0) } }
3.採集的代理方法
//MARK: AVCapture delegate extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate { func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { if videoOutPut?.connection(withMediaType: AVMediaTypeVideo) == connection { print("採集到視訊資料") }else{ print("採集到音訊資料") } } }
4.開始採集、結束採集、切換攝像頭方法呼叫
extension ViewController{
//開始採集
@IBAction func startCapture(_ sender: Any) {
print("startCapture")
session.startRunning()
movieOutPutFile()
}
//結束採集
@IBAction func endCapture(_ sender: Any) {
print("endCapture")
self.fileOutPut?.stopRecording()
session.stopRunning()
previewLayer?.removeFromSuperlayer()
}
//切換鏡頭
@IBAction func changeDirection(_ sender: Any) {
print("changeDirection")
guard let videoInput = videoInput else {
return
}
let position: AVCaptureDevicePosition = videoInput.device.position == .front ? .back : .front
guard let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] else{return}
guard let device = devices.filter({ $0.position == position }).first else {return}
guard let newInput = try? AVCaptureDeviceInput(device: device) else {return}
self.videoInput = newInput
session.beginConfiguration()
session.removeInput(videoInput)
if session.canAddInput(newInput) {
session.addInput(newInput)
}
session.commitConfiguration()
}
//寫入檔案
fileprivate func movieOutPutFile() {
let fileOutPut = AVCaptureMovieFileOutput()
let connection = fileOutPut.connection(withMediaType: AVMediaTypeVideo)
connection?.automaticallyAdjustsVideoMirroring = true
print(session)
session.beginConfiguration()
session.removeOutput(self.fileOutPut)
if session.canAddOutput(fileOutPut) {
session.addOutput(fileOutPut)
}
session.commitConfiguration()
self.fileOutPut = fileOutPut
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/glt.mp4"
fileOutPut.startRecording(toOutputFileURL: URL(fileURLWithPath: path), recordingDelegate: self)
}
}
5.寫入檔案代理
//MARK: 寫入檔案代理
extension ViewController: AVCaptureFileOutputRecordingDelegate {
func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {
print("開始錄製")
}
func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
print("結束錄製")
}
}