| 
					
				 | 
			
			
				@@ -12,6 +12,15 @@ import Foundation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import GPUImage 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import Photos 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public enum ExportError : Int { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case FileNotExist   = -31001 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case DataLost       = -31002 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case VoiceLost      = -31003 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case TotalDurError  = -31004 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case ExportExcept   = -31005 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case DiskNoSpace    = -31006 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public var progress: ((Float) -> Void)? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public var exportCompletion: ((Error?, URL?) -> Void)? 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -50,52 +59,51 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 切割视频素材 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (_, itemModel) in itemModels.enumerated() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                itemModel.videoStickers.removeAll() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                let dur = itemModel.materialDuraion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if synthesisAll { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // 保留全部 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    let dur = itemModel.materialDuraion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    let bgMovieInfo = splitBaseMaterial(timelineIn: totalDur, model_in: 0, duration: dur) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    bgMovieInfo.volumeGain = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    itemModel.videoStickers.append(bgMovieInfo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    totalDur += dur 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var subDur = 0.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    let drangs = itemModel.dealedDurationRanges 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    for srange in drangs { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if let localPath = itemModel.localPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if let localPath = itemModel.localPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if !FileManager.default.fileExists(atPath: localPath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        let error = NSError(domain: "err", code: ExportError.FileNotExist.rawValue, userInfo: ["msg": "file not exist"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    itemModel.videoStickers.removeAll() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if synthesisAll { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var subDur = 0.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        let drangs = itemModel.dealedDurationRanges 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        for srange in drangs { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             let range = srange.range 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             sticker.locationPath = localPath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             sticker.volumeGain = Float64(srange.isRecord ? originSoundInRecordVolumn*100 : originSoundVolumn*100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             itemModel.videoStickers.append(sticker) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             subDur += range.duration.seconds 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    totalDur += subDur 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var subDur = 0.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var drangs = itemModel.dealedDurationRanges.filter { srange in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        srange.isRecord == true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // 是否按录音顺序排列 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    let needSort = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if needSort { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        drangs.sort { range1, range2 in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            range1.index < range2.index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        totalDur += subDur 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var subDur = 0.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var drangs = itemModel.dealedDurationRanges.filter { srange in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            srange.isRecord == true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    for srange in drangs { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if let localPath = itemModel.localPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        // 是否按录音顺序排列 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        let needSort = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if needSort { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            drangs.sort { range1, range2 in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                range1.index < range2.index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        for srange in drangs { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             let range = srange.range 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            sticker.locationPath = localPath  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            sticker.locationPath = localPath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             sticker.volumeGain = Float64(srange.isRecord ? originSoundInRecordVolumn*100 : originSoundVolumn*100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             itemModel.videoStickers.append(sticker) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             subDur += range.duration.seconds 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        totalDur += subDur 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    totalDur += subDur 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             beginExport(synthesisAll: synthesisAll) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -159,7 +167,7 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         BFLog(1, message: "导出视频地址 \(outPutMP4URL)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         guard let itemData = data else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "voiceStickers count += nil"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let error = NSError(domain: "err", code: ExportError.DataLost.rawValue, userInfo: ["msg": "所有数据丢失"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -178,7 +186,7 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             itemModell.voiceStickers.count + partialResult 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }) else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             BFLog(1, message: "voiceStickers count += nil") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "voiceStickers count += nil"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let error = NSError(domain: "err", code: ExportError.VoiceLost.rawValue, userInfo: ["msg": "voiceStickers count += nil"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -186,7 +194,7 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         guard let totalDuration = data?.reduce(0, { partialResult, itemModell in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             itemModell.materialDuraion + partialResult 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }) else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "时长计算出错"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let error = NSError(domain: "err", code: ExportError.TotalDurError.rawValue, userInfo: ["msg": "时长计算出错"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -223,7 +231,14 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BFLog(1, message: "导出设置的码率为:\(orgeBitRate)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            BFLog(1, message: "导出设置的码率为:\(Double(orgeBitRate)/1024.0/1024.0)M") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let preSize = Double(orgeBitRate) * totalDuration / (1024*1024) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let freeSize = PQBridgeObject.getPhoneDiskFreeSize() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if preSize + 100.0 > freeSize { // 存储完后磁盘剩余至少100M 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let error = NSError(domain: "err", code: ExportError.DiskNoSpace.rawValue, userInfo: ["msg":"磁盘空间不足"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let tempBeginExport = Date().timeIntervalSince1970 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if exporter!.prepare(videoSize: outputSize, videoAverageBitRate: orgeBitRate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 exporter!.start(playeTimeRange: CMTimeRange(start: CMTime.zero, end: synthesisAll ? CMTime(seconds: totalDuration, preferredTimescale: 100) : composition.duration)) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -248,7 +263,7 @@ public class BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self?.exportCompletion?(nil, url) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    let error = NSError(domain: "err", code: -1, userInfo: nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    let error = NSError(domain: "err", code: ExportError.ExportExcept.rawValue, userInfo: ["msg":"导出异常失败"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self?.exportCompletion?(error as Error, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     cShowHUB(superView: nil, msg: "导出失败") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -298,7 +313,7 @@ extension BFRecordExport { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 BFLog(message: "音频音量 为0 不添加") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sticker.volumeGain = 50 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            sticker.volumeGain = 50 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             totalDuration = max(totalDuration, sticker.duration) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 |