iOS GPUImage音視訊採集以及美顏功能
阿新 • • 發佈:2019-01-11
iOS GPUImage音視訊採集以及美顏功能
GPUImageStillCamera:用於拍攝當前手機的畫面, 並且儲存圖片
GPUImageVideoCamera:通常用於實時視訊的錄製使用方法:GPUImageStillCamera \ GPUImageVideoCamera>GPUImageFilter->GPUImageView 攝像機轉到濾鏡再轉到view上
本篇部落格Demo:iOS GPUImage音視訊採集以及美顏功能
初始化需要用到的屬性
fileprivate lazy var camera: GPUImageVideoCamera? = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front) fileprivate lazy var preView: GPUImageView = { let preView = GPUImageView(frame: self.view.bounds) return preView }() let saturationFilter = GPUImageSaturationFilter() // 飽和 let bilateralFilter = GPUImageBilateralFilter() // 磨皮 let brightnessFilter = GPUImageBrightnessFilter() // 美白 let exposureFilter = GPUImageExposureFilter() // 曝光 fileprivate var player: AVPlayer? fileprivate var isEndRecording = false // 視訊存放路徑Url var fileURL : URL { return URL(fileURLWithPath: pathString) } //視訊存放路徑 var pathString: String { return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/test.mp4" } // 建立寫入物件 fileprivate lazy var movieWriter : GPUImageMovieWriter = { [weak self] in if FileManager.default.fileExists(atPath: (self?.pathString)!) { try? FileManager.default.removeItem(atPath: (self?.pathString)!) } let movieWriter = GPUImageMovieWriter(movieURL: self?.fileURL, size: (self?.view.bounds.size)!) movieWriter?.encodingLiveVideo = true return movieWriter! }()
建立camera以及濾鏡組
fileprivate func conifgCamera() { //建立預覽的View view.insertSubview(preView, at: 0) //設定camera方向 camera?.outputImageOrientation = .portrait camera?.horizontallyMirrorFrontFacingCamera = true ///防止允許聲音通過的情況下,避免錄製第一幀黑屏閃屏 camera?.addAudioInputsAndOutputs() //獲取濾鏡組 let filterGroup = getGroupFilters() //設定預設值 bilateralFilter.distanceNormalizationFactor = 5.5 exposureFilter.exposure = 0 brightnessFilter.brightness = 0 saturationFilter.saturation = 1.0 //設定GPUImage的響應鏈 camera?.addTarget(filterGroup) filterGroup.addTarget(preView) //開始採集視訊 camera?.startCapture() // 將writer設定成濾鏡的target filterGroup.addTarget(movieWriter) camera?.delegate = self camera?.audioEncodingTarget = movieWriter movieWriter.startRecording() } fileprivate func getGroupFilters() -> GPUImageFilterGroup { //建立濾鏡組 let filterGroup = GPUImageFilterGroup() //建立濾鏡(設定濾鏡的引來關係) bilateralFilter.addTarget(brightnessFilter) brightnessFilter.addTarget(exposureFilter) exposureFilter.addTarget(saturationFilter) //設定濾鏡起點 終點的filter filterGroup.initialFilters = [bilateralFilter] filterGroup.terminalFilter = saturationFilter return filterGroup }
功能以及方法的呼叫
//翻轉 @objc fileprivate func pickUpCameraSelected() { camera?.rotateCamera() } //濾鏡 @objc fileprivate func filterCameraSelected() { filterView.show() } //結束錄製 @objc fileprivate func endRecordSelected() { isEndRecording = true preView.removeFromSuperview() movieWriter.finishRecording() let filterGroup = getGroupFilters() filterGroup.removeTarget(movieWriter) camera?.stopCapture() } //播放 @objc fileprivate func playRecordSelected() { print(fileURL) if !FileManager.default.fileExists(atPath: pathString) { showAlert("播放路徑不存在") return } let playerItem = AVPlayerItem(url: fileURL) player = AVPlayer(playerItem: playerItem) let layer = AVPlayerLayer(player: player) layer.frame = CGRect(x: (kWidth - 220)/2.0, y: 210, width: 220, height: 220) view.layer.addSublayer(layer) player?.play() } //拍照 @objc fileprivate func takePhotoSelected() { guard let camera = camera else { fatalError("請退出程式重新錄製!") } if camera.isMember(of: GPUImageVideoCamera.self) { showAlert("請檢視takePhotoSelected方法的說明") return } /*說明: GPUImageVideoCamera:通常用於實時視訊的錄製 GPUImageStillCamera:用於拍攝當前手機的畫面, 並且儲存圖片 1. 將 fileprivate lazy var camera: GPUImageVideoCamera? = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front) 改為 fileprivate lazy var camera: GPUImageStillCamera? = GPUImageStillCamera(sessionPreset: AVCaptureSessionPresetHigh, cameraPosition: .front) 2. 取消以下注釋 */ /* camera.capturePhotoAsImageProcessedUp(toFilter: getGroupFilters(), withCompletionHandler: {[weak self] (image, error) in if error == nil { UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil) self?.showAlert("圖片儲存成功,請退出程式重新錄製!") }else{ self?.showAlert("圖片儲存失敗,請退出程式重新錄製!") } self?.endRecordSelected() }) */ }
美顏效果的切換處理,可以參考 iOS GPUImage影象處理
//根據滑動改變美顏效果
fileprivate func configSliderChange() {
filterView.sliderDidValueChanged = {[weak self] (_, slider, type) in
print(slider.value)
switch type {
case .bilateralFilter:
self?.bilateralFilter.distanceNormalizationFactor = 10.0 - CGFloat(slider.value)
break
case .exposureFilter:
self?.exposureFilter.exposure = CGFloat(slider.value) * 20.0 - 10.0
break
case .brightnessFilter:
self?.brightnessFilter.brightness = CGFloat(slider.value) * 2.0 - 1.0
break
case .saturationFilter:
self?.saturationFilter.saturation = CGFloat(slider.value) * 2.0
break
}
}
}
//開關美顏功能
fileprivate func configSwitchChange() {
filterView.switchDidValueChanged = {[weak self] (_, filterSwitch, isOpen) in
if isOpen {
self?.camera?.removeAllTargets()
let group = self?.getGroupFilters()
self?.camera?.addTarget(group)
group?.addTarget(self?.preView)
}else{
self?.camera?.removeAllTargets()
self?.camera?.addTarget(self?.preView)
}
}
}
效果圖如下: