Browse Source

add codeformat(swiftformat)

wenweiwei 3 years ago
parent
commit
118027205c
23 changed files with 943 additions and 931 deletions
  1. 65 0
      .swiftformat
  2. 3 3
      BFRecordScreenKit/Classes/BFRSComm.swift
  3. 86 94
      BFRecordScreenKit/Classes/BFRecordExport.swift
  4. 40 46
      BFRecordScreenKit/Classes/BFRecordItemModel.swift
  5. 17 19
      BFRecordScreenKit/Classes/BFVideoThumbImageFetchHelper.swift
  6. 8 10
      BFRecordScreenKit/Classes/BFVideoThumbProgressStrategy.swift
  7. 21 24
      BFRecordScreenKit/Classes/BFVoiceRecordManager.swift
  8. 280 304
      BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift
  9. 0 1
      BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenImageController.swift
  10. 0 1
      BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenVideoController.swift
  11. 12 19
      BFRecordScreenKit/Classes/RecordScreen/View/BFIntroduceToolView.swift
  12. 84 93
      BFRecordScreenKit/Classes/RecordScreen/View/BFRecordAvatarView.swift
  13. 25 37
      BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleEditView.swift
  14. 99 117
      BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleSettingView.swift
  15. 46 50
      BFRecordScreenKit/Classes/RecordScreen/View/BFVideoThumbProgressView.swift
  16. 18 23
      BFRecordScreenKit/Classes/RecordScreen/ViewModel/BFRecordScreenViewModel.swift
  17. 11 16
      Example/BFRecordScreenKit/AppDelegate.swift
  18. 6 7
      Example/BFRecordScreenKit/IntroduceController.swift
  19. 23 27
      Example/BFRecordScreenKit/PhotoVideoListController.swift
  20. 19 20
      Example/BFRecordScreenKit/VideoExportController.swift
  21. 8 13
      Example/BFRecordScreenKit/ViewController.swift
  22. 5 7
      Example/Tests/Tests.swift
  23. 67 0
      rules.swiftformat

+ 65 - 0
.swiftformat

@@ -0,0 +1,65 @@
+--allman false
+--assetliterals visual-width
+--beforemarks 
+--binarygrouping none
+--categorymark "MARK: %c"
+--classthreshold 0
+--closingparen balanced
+--commas always
+--conflictmarkers reject
+--decimalgrouping none
+--elseposition same-line
+--enumthreshold 0
+--exponentcase lowercase
+--exponentgrouping disabled
+--extensionacl on-extension
+--extensionlength 0
+--extensionmark "MARK: - %t + %c"
+--fractiongrouping disabled
+--fragment false
+--funcattributes preserve
+--groupedextension "MARK: %c"
+--guardelse auto
+--header ignore
+--hexgrouping 4,8
+--hexliteralcase uppercase
+--ifdef indent
+--importgrouping alphabetized
+--indent 4
+--indentcase false
+--lifecycle 
+--linebreaks lf
+--markextensions always
+--marktypes always
+--maxwidth none
+--modifierorder 
+--nevertrailing 
+--nospaceoperators ...,..<
+--nowrapoperators 
+--octalgrouping none
+--operatorfunc spaced
+--organizetypes class,enum,struct
+--patternlet hoist
+--ranges spaced
+--redundanttype inferred
+--self remove
+--selfrequired 
+--semicolons inline
+--shortoptionals always
+--smarttabs enabled
+--stripunusedargs closure-only
+--structthreshold 0
+--tabwidth unspecified
+--trailingclosures 
+--trimwhitespace always
+--typeattributes preserve
+--typemark "MARK: - %t"
+--varattributes preserve
+--voidtype void
+--wraparguments preserve
+--wrapcollections preserve
+--wrapconditions preserve
+--wrapparameters preserve
+--wrapreturntype preserve
+--xcodeindentation disabled
+--yodaswap always

+ 3 - 3
BFRecordScreenKit/Classes/BFRSComm.swift

@@ -9,7 +9,7 @@ import Foundation
 
 
 import BFCommonKit
 import BFCommonKit
 
 
-//class BFUIConfig{}
+// class BFUIConfig{}
 
 
 public func imageInRecordScreenKit(by name: String) -> UIImage? {
 public func imageInRecordScreenKit(by name: String) -> UIImage? {
     return UIImage(named: name, in: currentBundle(), compatibleWith: nil)
     return UIImage(named: name, in: currentBundle(), compatibleWith: nil)
@@ -19,7 +19,7 @@ func currentBundle() -> Bundle? {
     return Bundle.current(moduleName: "BFRecordScreenKit", isAssets: false)
     return Bundle.current(moduleName: "BFRecordScreenKit", isAssets: false)
 }
 }
 
 
-//func ThemeStyleGreen() -> UIColor {
+// func ThemeStyleGreen() -> UIColor {
 //    return UIColor.hexColor(hexadecimal: "#28BE67")
 //    return UIColor.hexColor(hexadecimal: "#28BE67")
-//}
+// }
 public var ThemeStyleColor = UIColor.hexColor(hexadecimal: "#28BE67")
 public var ThemeStyleColor = UIColor.hexColor(hexadecimal: "#28BE67")

+ 86 - 94
BFRecordScreenKit/Classes/BFRecordExport.swift

@@ -5,19 +5,19 @@
 //  Created by 胡志强 on 2021/11/25.
 //  Created by 胡志强 on 2021/11/25.
 //  录屏视频导出
 //  录屏视频导出
 
 
-import Foundation
 import AVFoundation
 import AVFoundation
-import Photos
-import GPUImage
 import BFCommonKit
 import BFCommonKit
 import BFMediaKit
 import BFMediaKit
+import Foundation
+import GPUImage
+import Photos
 
 
 public class BFRecordExport {
 public class BFRecordExport {
-    public var progress : ((Float)->Void)?
-    public var exportCompletion : ((Error?, URL?)->Void)?
-        
-    public var data:[BFRecordItemModel]? {
-        didSet{
+    public var progress: ((Float) -> Void)?
+    public var exportCompletion: ((Error?, URL?) -> Void)?
+
+    public var data: [BFRecordItemModel]? {
+        didSet {
             if data?.count ?? 0 > 0 {
             if data?.count ?? 0 > 0 {
                 for item in data! {
                 for item in data! {
                     item.generationTimeRanges()
                     item.generationTimeRanges()
@@ -27,30 +27,28 @@ public class BFRecordExport {
     }
     }
 
 
     var count = 0
     var count = 0
-    
+
     var stickerRanges = [CMTimeRange]()
     var stickerRanges = [CMTimeRange]()
-    
-    var exporter : PQCompositionExporter?
+
+    var exporter: PQCompositionExporter?
 //    var mStickers = [PQEditVisionTrackMaterialsModel]()
 //    var mStickers = [PQEditVisionTrackMaterialsModel]()
-    
-    deinit {
-    }
-    public init(){}
 
 
-    
-    //MARK: -
+    deinit {}
+
+    public init() {}
+
+    // MARK: -
 
 
     /// synthesisAll: 合成所有还是只合成录音部分
     /// synthesisAll: 合成所有还是只合成录音部分
-    public func startExprot(synthesisAll:Bool){
+    public func startExprot(synthesisAll: Bool) {
         // 1,背景视频素材
         // 1,背景视频素材
         if let itemModels = data {
         if let itemModels = data {
-            
             var totalDur = 0.0
             var totalDur = 0.0
-            
+
             // 切割视频素材
             // 切割视频素材
             for (_, itemModel) in itemModels.enumerated() {
             for (_, itemModel) in itemModels.enumerated() {
                 itemModel.videoStickers.removeAll()
                 itemModel.videoStickers.removeAll()
-                
+
                 if synthesisAll {
                 if synthesisAll {
                     // 保留全部
                     // 保留全部
                     //                        let bgMovieInfo = splitBaseMaterial(timelineIn: totalDur, model_in: 0, duration: dur)
                     //                        let bgMovieInfo = splitBaseMaterial(timelineIn: totalDur, model_in: 0, duration: dur)
@@ -61,7 +59,7 @@ public class BFRecordExport {
                     let drangs = itemModel.dealedDurationRanges
                     let drangs = itemModel.dealedDurationRanges
                     for srange in drangs {
                     for srange in drangs {
                         let range = srange.range
                         let range = srange.range
-                        let sticker = splitBaseMaterial(timelineIn: (totalDur + subDur), model_in: range.start.seconds, duration: range.duration.seconds)
+                        let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds)
                         sticker.volumeGain = srange.isRecord ? 0 : 100
                         sticker.volumeGain = srange.isRecord ? 0 : 100
                         itemModel.videoStickers.append(sticker)
                         itemModel.videoStickers.append(sticker)
                         subDur += range.duration.seconds
                         subDur += range.duration.seconds
@@ -73,7 +71,7 @@ public class BFRecordExport {
                     var drangs = itemModel.dealedDurationRanges.filter { srange in
                     var drangs = itemModel.dealedDurationRanges.filter { srange in
                         srange.isRecord == true
                         srange.isRecord == true
                     }
                     }
-                    
+
                     // 是否按录音顺序排列
                     // 是否按录音顺序排列
                     let needSort = false
                     let needSort = false
                     if needSort {
                     if needSort {
@@ -83,7 +81,7 @@ public class BFRecordExport {
                     }
                     }
                     for srange in drangs {
                     for srange in drangs {
                         let range = srange.range
                         let range = srange.range
-                        let sticker = splitBaseMaterial(timelineIn: (totalDur + subDur), model_in: range.start.seconds, duration: range.duration.seconds)
+                        let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds)
                         sticker.volumeGain = 0
                         sticker.volumeGain = 0
                         itemModel.videoStickers.append(sticker)
                         itemModel.videoStickers.append(sticker)
                         subDur += range.duration.seconds
                         subDur += range.duration.seconds
@@ -91,40 +89,38 @@ public class BFRecordExport {
                     totalDur += subDur
                     totalDur += subDur
                 }
                 }
             }
             }
-            beginExport(synthesisAll:synthesisAll)
+            beginExport(synthesisAll: synthesisAll)
         }
         }
     }
     }
-    
-    public func cancelExport(){
-        self.exporter?.cancel()
+
+    public func cancelExport() {
+        exporter?.cancel()
     }
     }
-    
-    public func clearFileCache(){
-        data?.forEach({ itemModel in
+
+    public func clearFileCache() {
+        data?.forEach { itemModel in
             itemModel.voiceStickers.forEach { model in
             itemModel.voiceStickers.forEach { model in
-                if let localPath = model.wavFilePath{
+                if let localPath = model.wavFilePath {
                     try? FileManager.default.removeItem(atPath: localPath)
                     try? FileManager.default.removeItem(atPath: localPath)
                 }
                 }
             }
             }
-        })
+        }
     }
     }
-    
-    
+
     enum DispatchError: Error {
     enum DispatchError: Error {
         case timeout
         case timeout
     }
     }
-    
-    func getOutputFilePath() -> URL{
+
+    func getOutputFilePath() -> URL {
         var outPutMP4Path = exportVideosDirectory
         var outPutMP4Path = exportVideosDirectory
         if !directoryIsExists(dicPath: outPutMP4Path) {
         if !directoryIsExists(dicPath: outPutMP4Path) {
             createDirectory(path: outPutMP4Path)
             createDirectory(path: outPutMP4Path)
         }
         }
         outPutMP4Path.append("video_\(String.qe.timestamp()).mp4")
         outPutMP4Path.append("video_\(String.qe.timestamp()).mp4")
         return URL(fileURLWithPath: outPutMP4Path)
         return URL(fileURLWithPath: outPutMP4Path)
-        
     }
     }
-    
-    func splitBaseMaterial(timelineIn:Double, model_in:Double, duration:Double) -> PQEditVisionTrackMaterialsModel{
+
+    func splitBaseMaterial(timelineIn: Double, model_in: Double, duration: Double) -> PQEditVisionTrackMaterialsModel {
         let bgMovieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
         let bgMovieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
         bgMovieInfo.type = StickerType.VIDEO.rawValue
         bgMovieInfo.type = StickerType.VIDEO.rawValue
         bgMovieInfo.timelineIn = timelineIn
         bgMovieInfo.timelineIn = timelineIn
@@ -139,11 +135,11 @@ public class BFRecordExport {
             bgMovieInfo.locationPath = localPath
             bgMovieInfo.locationPath = localPath
         }
         }
         BFLog(1, message: "hhh- timIn:\(timelineIn), modIn:\(model_in), dur:\(duration)")
         BFLog(1, message: "hhh- timIn:\(timelineIn), modIn:\(model_in), dur:\(duration)")
-        
+
         return bgMovieInfo
         return bgMovieInfo
     }
     }
-    
-    func beginExport(synthesisAll:Bool) {
+
+    func beginExport(synthesisAll: Bool) {
         // 输出视频地址
         // 输出视频地址
 //        exprotVideo()
 //        exprotVideo()
 //        return;
 //        return;
@@ -154,13 +150,13 @@ public class BFRecordExport {
         outPutMP4Path.append("video_\(String.qe.timestamp()).mp4")
         outPutMP4Path.append("video_\(String.qe.timestamp()).mp4")
         let outPutMP4URL = URL(fileURLWithPath: outPutMP4Path)
         let outPutMP4URL = URL(fileURLWithPath: outPutMP4Path)
         BFLog(1, message: "导出视频地址 \(outPutMP4URL)")
         BFLog(1, message: "导出视频地址 \(outPutMP4URL)")
-        
+
         guard let itemData = data else {
         guard let itemData = data else {
-            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"voiceStickers count += nil"])
-            self.exportCompletion?(error as Error, nil)
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "voiceStickers count += nil"])
+            exportCompletion?(error as Error, nil)
             return
             return
         }
         }
-        
+
         // 处理导出
         // 处理导出
         var voiceList = [PQVoiceModel]()
         var voiceList = [PQVoiceModel]()
         var videoStickers = [PQEditVisionTrackMaterialsModel]()
         var videoStickers = [PQEditVisionTrackMaterialsModel]()
@@ -170,54 +166,52 @@ public class BFRecordExport {
             videoStickers.append(contentsOf: itemModel.videoStickers)
             videoStickers.append(contentsOf: itemModel.videoStickers)
             titleStickers.append(contentsOf: itemModel.titleStickers)
             titleStickers.append(contentsOf: itemModel.titleStickers)
         }
         }
-        
-        
+
         guard let voiceCount = data?.reduce(0, { partialResult, itemModell in
         guard let voiceCount = data?.reduce(0, { partialResult, itemModell in
             itemModell.voiceStickers.count + partialResult
             itemModell.voiceStickers.count + partialResult
         }) else {
         }) else {
             BFLog(1, message: "voiceStickers count += nil")
             BFLog(1, message: "voiceStickers count += nil")
-            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"voiceStickers count += nil"])
-            self.exportCompletion?(error as Error, nil)
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "voiceStickers count += nil"])
+            exportCompletion?(error as Error, nil)
             return
             return
         }
         }
-        
+
         guard let totalDuration = data?.reduce(0, { partialResult, itemModell in
         guard let totalDuration = data?.reduce(0, { partialResult, itemModell in
-            (itemModell.materialDuraion ) + partialResult
+            itemModell.materialDuraion + partialResult
         }) else {
         }) else {
-            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"时长计算出错"])
-            self.exportCompletion?(error as Error, nil)
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg": "时长计算出错"])
+            exportCompletion?(error as Error, nil)
             return
             return
         }
         }
-        
+
         // 有录音操作或者多个视频,就会进入合成步骤,否则就是一个没有处理的素材,直接导出就行了
         // 有录音操作或者多个视频,就会进入合成步骤,否则就是一个没有处理的素材,直接导出就行了
         if voiceCount > 0 || videoStickers.count > 1 {
         if voiceCount > 0 || videoStickers.count > 1 {
+            let (audioMix, composition) = mergeAudio(videoStickers: videoStickers, audios: voiceList, synthesisAll: synthesisAll)
 
 
-            let (audioMix, composition) = mergeAudio(videoStickers: videoStickers, audios: voiceList,synthesisAll:synthesisAll)
-            
             let filter = videoStickers.map { sticker in
             let filter = videoStickers.map { sticker in
                 PQMovieFilter(movieSticker: sticker)
                 PQMovieFilter(movieSticker: sticker)
             }
             }
-  
+
             exporter = PQCompositionExporter(asset: composition, videoComposition: nil, audioMix: audioMix, filters: filter, animationTool: nil, exportURL: outPutMP4URL)
             exporter = PQCompositionExporter(asset: composition, videoComposition: nil, audioMix: audioMix, filters: filter, animationTool: nil, exportURL: outPutMP4URL)
-            
+
 //            let asset = data?.first?.baseMaterial // 可能为空
 //            let asset = data?.first?.baseMaterial // 可能为空
 
 
-            let size = UIScreen.main.bounds.size //getVideoSize(asset: asset!)
+            let size = UIScreen.main.bounds.size // getVideoSize(asset: asset!)
             var orgeBitRate = Int(size.width * size.height * 3)
             var orgeBitRate = Int(size.width * size.height * 3)
-            
+
             for stick in videoStickers {
             for stick in videoStickers {
                 if stick.type == StickerType.VIDEO.rawValue {
                 if stick.type == StickerType.VIDEO.rawValue {
                     let asset = AVURLAsset(url: URL(fileURLWithPath: stick.locationPath), options: avAssertOptions)
                     let asset = AVURLAsset(url: URL(fileURLWithPath: stick.locationPath), options: avAssertOptions)
-                    
+
                     let cbr = asset.tracks(withMediaType: .video).first?.estimatedDataRate
                     let cbr = asset.tracks(withMediaType: .video).first?.estimatedDataRate
                     if Int(cbr ?? 0) > orgeBitRate {
                     if Int(cbr ?? 0) > orgeBitRate {
                         orgeBitRate = Int(cbr ?? 0)
                         orgeBitRate = Int(cbr ?? 0)
                     }
                     }
                 }
                 }
             }
             }
-            
+
             BFLog(message: "导出设置的码率为:\(orgeBitRate)")
             BFLog(message: "导出设置的码率为:\(orgeBitRate)")
- 
+
             if exporter!.prepare(videoSize: size, videoAverageBitRate: orgeBitRate) {
             if exporter!.prepare(videoSize: size, videoAverageBitRate: orgeBitRate) {
                 exporter!.start(playeTimeRange: CMTimeRange(start: CMTime.zero, end: synthesisAll ? CMTime(seconds: totalDuration, preferredTimescale: 100) : composition.duration))
                 exporter!.start(playeTimeRange: CMTimeRange(start: CMTime.zero, end: synthesisAll ? CMTime(seconds: totalDuration, preferredTimescale: 100) : composition.duration))
             }
             }
@@ -232,9 +226,9 @@ public class BFRecordExport {
                 // 输出视频时长
                 // 输出视频时长
                 if let url = url {
                 if let url = url {
                     let outSeconds = CMTimeGetSeconds(AVAsset(url: url).duration)
                     let outSeconds = CMTimeGetSeconds(AVAsset(url: url).duration)
-                    
+
                     BFLog(1, message: "无水印的视频导出完成: \(String(describing: url)) 生成视频时长为:\(outSeconds)")
                     BFLog(1, message: "无水印的视频导出完成: \(String(describing: url)) 生成视频时长为:\(outSeconds)")
-                    cShowHUB(superView: nil, msg: ( outSeconds == 0) ? "合成失败请重试。" : "合成成功")
+                    cShowHUB(superView: nil, msg: (outSeconds == 0) ? "合成失败请重试。" : "合成成功")
                     self?.exportCompletion?(nil, url)
                     self?.exportCompletion?(nil, url)
 
 
                 } else {
                 } else {
@@ -242,47 +236,46 @@ public class BFRecordExport {
                     self?.exportCompletion?(error as Error, nil)
                     self?.exportCompletion?(error as Error, nil)
                     cShowHUB(superView: nil, msg: "导出失败")
                     cShowHUB(superView: nil, msg: "导出失败")
                 }
                 }
-                
+
                 // 导出完成后取消导出
                 // 导出完成后取消导出
                 self?.exporter?.cancel()
                 self?.exporter?.cancel()
             }
             }
         } else {
         } else {
             // 没有处理,直接copy原文件
             // 没有处理,直接copy原文件
-            if let localPath = data?.first?.localPath{
-                self.exportCompletion?(nil, URL(fileURLWithPath: localPath))
+            if let localPath = data?.first?.localPath {
+                exportCompletion?(nil, URL(fileURLWithPath: localPath))
             }
             }
         }
         }
-
     }
     }
-    
-    func dealAsset(){
+
+    func dealAsset() {
 //        asset?.tracks.first(where: { track in
 //        asset?.tracks.first(where: { track in
 //            if track.mediaType == .audio{
 //            if track.mediaType == .audio{
 //
 //
 //            }
 //            }
 //        })
 //        })
     }
     }
-    
-    func getVideoSize(asset:AVURLAsset) -> CGSize{
+
+    func getVideoSize(asset: AVURLAsset) -> CGSize {
         var size = CGSize.zero
         var size = CGSize.zero
-        asset.tracks.forEach({ track in
-            if track.mediaType == .video{
+        asset.tracks.forEach { track in
+            if track.mediaType == .video {
                 let realSize = __CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
                 let realSize = __CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
                 size = CGSize(width: ceil(abs(realSize.width)), height: ceil(abs(realSize.height)))
                 size = CGSize(width: ceil(abs(realSize.width)), height: ceil(abs(realSize.height)))
             }
             }
-        })
-        
+        }
+
         return size
         return size
     }
     }
 }
 }
 
 
 extension BFRecordExport {
 extension BFRecordExport {
-    func mergeAudio(videoStickers:[PQEditVisionTrackMaterialsModel], audios:[PQVoiceModel]?, synthesisAll:Bool) -> (AVMutableAudioMix, AVMutableComposition){
+    func mergeAudio(videoStickers: [PQEditVisionTrackMaterialsModel], audios: [PQVoiceModel]?, synthesisAll: Bool) -> (AVMutableAudioMix, AVMutableComposition) {
         let composition = AVMutableComposition()
         let composition = AVMutableComposition()
         let audioMix = AVMutableAudioMix()
         let audioMix = AVMutableAudioMix()
         var tempParameters = [AVMutableAudioMixInputParameters]()
         var tempParameters = [AVMutableAudioMixInputParameters]()
-        
-        var totalDuration : Float64 = 0
+
+        var totalDuration: Float64 = 0
         for sticker in videoStickers {
         for sticker in videoStickers {
             if sticker.volumeGain == 0 {
             if sticker.volumeGain == 0 {
                 // 如果添加了会有刺啦音
                 // 如果添加了会有刺啦音
@@ -295,18 +288,18 @@ extension BFRecordExport {
         }
         }
         if let voices = audios {
         if let voices = audios {
             if synthesisAll {
             if synthesisAll {
-                tempParameters += mergeRecordVoiceAll(voices:voices, composition)
-            }else {
-                tempParameters += mergeRecordVoiceOnly(voices:voices, composition)
+                tempParameters += mergeRecordVoiceAll(voices: voices, composition)
+            } else {
+                tempParameters += mergeRecordVoiceOnly(voices: voices, composition)
             }
             }
         }
         }
         audioMix.inputParameters = tempParameters
         audioMix.inputParameters = tempParameters
         return (audioMix, composition)
         return (audioMix, composition)
     }
     }
-    
-    func mergeRecordVoiceOnly(voices:[PQVoiceModel], _ composition:AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
+
+    func mergeRecordVoiceOnly(voices: [PQVoiceModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
         var tempParameters = [AVMutableAudioMixInputParameters]()
         var tempParameters = [AVMutableAudioMixInputParameters]()
-        var totalDur:Double = 0.0
+        var totalDur: Double = 0.0
         for model in voices {
         for model in voices {
             if model.volume == 0 {
             if model.volume == 0 {
                 // 如果添加了会有刺啦音
                 // 如果添加了会有刺啦音
@@ -322,15 +315,15 @@ extension BFRecordExport {
             sticker.aptDuration = duration
             sticker.aptDuration = duration
             sticker.duration = duration
             sticker.duration = duration
             sticker.locationPath = model.wavFilePath
             sticker.locationPath = model.wavFilePath
-            sticker.volumeGain = 100 //Float64(model.volume)
+            sticker.volumeGain = 100 // Float64(model.volume)
             tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
             tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
             totalDur += duration
             totalDur += duration
         }
         }
 
 
         return tempParameters
         return tempParameters
     }
     }
-    
-    func mergeRecordVoiceAll(voices:[PQVoiceModel], _ composition:AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
+
+    func mergeRecordVoiceAll(voices: [PQVoiceModel], _ composition: AVMutableComposition) -> [AVMutableAudioMixInputParameters] {
         var tempParameters = [AVMutableAudioMixInputParameters]()
         var tempParameters = [AVMutableAudioMixInputParameters]()
         for model in voices {
         for model in voices {
             if model.volume == 0 {
             if model.volume == 0 {
@@ -345,11 +338,10 @@ extension BFRecordExport {
             sticker.aptDuration = model.endTime - model.startTime
             sticker.aptDuration = model.endTime - model.startTime
             sticker.duration = sticker.aptDuration
             sticker.duration = sticker.aptDuration
             sticker.locationPath = model.wavFilePath
             sticker.locationPath = model.wavFilePath
-            sticker.volumeGain = 100 //Float64(model.volume)
+            sticker.volumeGain = 100 // Float64(model.volume)
             tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
             tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
         }
         }
-        
+
         return tempParameters
         return tempParameters
     }
     }
-    
 }
 }

+ 40 - 46
BFRecordScreenKit/Classes/BFRecordItemModel.swift

@@ -5,55 +5,53 @@
 //  Created by 胡志强 on 2021/12/6.
 //  Created by 胡志强 on 2021/12/6.
 //
 //
 
 
+import BFCommonKit
+import BFMediaKit
 import Foundation
 import Foundation
 import Photos
 import Photos
-import BFMediaKit
-import BFCommonKit
 
 
 struct SplitRecordRange {
 struct SplitRecordRange {
-    var isRecord:Bool = false
-    var range:CMTimeRange
-    var index:Int
+    var isRecord: Bool = false
+    var range: CMTimeRange
+    var index: Int
 }
 }
 
 
 public class BFRecordItemModel: NSObject {
 public class BFRecordItemModel: NSObject {
 //    var baseMaterial : AVURLAsset?
 //    var baseMaterial : AVURLAsset?
-    var localPath : String?
+    var localPath: String?
     var materialDuraion: Double = 0.0
     var materialDuraion: Double = 0.0
-    var fetchCoverImg : ((UIImage)->Void)?
-    var fetchAVUrlAsset : ((AVURLAsset)->Void)?
-    var fetchPlayItem : ((AVPlayerItem)->Void)?
-    var dealedDurationRanges = [SplitRecordRange]()                     // 录音切割的时间区间,合成导出时计算
-    public var voiceStickers = [PQVoiceModel]()                         //
-    public var videoStickers = [PQEditVisionTrackMaterialsModel]()      // 合成导出时计算
-    public var imageStickers = [PQEditVisionTrackMaterialsModel]()      //
-    public var titleStickers = [PQEditSubTitleModel]()                  // 字幕贴纸
-    public var coverImg : UIImage?
+    var fetchCoverImg: ((UIImage) -> Void)?
+    var fetchAVUrlAsset: ((AVURLAsset) -> Void)?
+    var fetchPlayItem: ((AVPlayerItem) -> Void)?
+    var dealedDurationRanges = [SplitRecordRange]() // 录音切割的时间区间,合成导出时计算
+    public var voiceStickers = [PQVoiceModel]() //
+    public var videoStickers = [PQEditVisionTrackMaterialsModel]() // 合成导出时计算
+    public var imageStickers = [PQEditVisionTrackMaterialsModel]() //
+    public var titleStickers = [PQEditSubTitleModel]() // 字幕贴纸
+    public var coverImg: UIImage?
     public var index = 0
     public var index = 0
     public var width = 0
     public var width = 0
     public var height = 0
     public var height = 0
-    
-    func initOriginData(phasset:PHAsset){
+
+    func initOriginData(phasset: PHAsset) {
         width = phasset.pixelWidth
         width = phasset.pixelWidth
         height = phasset.pixelHeight
         height = phasset.pixelHeight
-        
+
         fetchCoverImage(phasset)
         fetchCoverImage(phasset)
         fetchPlayItem(phasset)
         fetchPlayItem(phasset)
         fetchAVUrlAsset(phasset)
         fetchAVUrlAsset(phasset)
-        
     }
     }
-    
-    func fetchCoverImage(_ phasset:PHAsset) {
+
+    func fetchCoverImage(_ phasset: PHAsset) {
         let option = PHImageRequestOptions()
         let option = PHImageRequestOptions()
-        option.isNetworkAccessAllowed = true //允许下载iCloud的图片
+        option.isNetworkAccessAllowed = true // 允许下载iCloud的图片
         option.resizeMode = .fast
         option.resizeMode = .fast
         option.deliveryMode = .highQualityFormat
         option.deliveryMode = .highQualityFormat
         PHImageManager.default().requestImage(for: phasset,
         PHImageManager.default().requestImage(for: phasset,
-                                       targetSize: CGSize(width: width, height: height),
-                                      contentMode: .aspectFit,
-                                          options: option)
-        { [weak self] (image, nil) in
-             // 设置首帧/封面
+                                              targetSize: CGSize(width: width, height: height),
+                                              contentMode: .aspectFit,
+                                              options: option) { [weak self] image, _ in
+            // 设置首帧/封面
             if image != nil {
             if image != nil {
                 self?.fetchCoverImg?(image!)
                 self?.fetchCoverImg?(image!)
                 self?.coverImg = image
                 self?.coverImg = image
@@ -61,15 +59,14 @@ public class BFRecordItemModel: NSObject {
         }
         }
     }
     }
 
 
-    func fetchPlayItem(_ phasset:PHAsset) {
+    func fetchPlayItem(_ phasset: PHAsset) {
         let options = PHVideoRequestOptions()
         let options = PHVideoRequestOptions()
         options.isNetworkAccessAllowed = true
         options.isNetworkAccessAllowed = true
         options.deliveryMode = .automatic
         options.deliveryMode = .automatic
         if phasset.mediaType == .image {
         if phasset.mediaType == .image {
-            
-        }else if phasset.mediaType == .video{
-            PHImageManager.default().requestPlayerItem(forVideo:phasset, options: options, resultHandler: { [weak self] playerItem, info in
-                
+        } else if phasset.mediaType == .video {
+            PHImageManager.default().requestPlayerItem(forVideo: phasset, options: options, resultHandler: { [weak self] playerItem, _ in
+
                 guard let item = playerItem else {
                 guard let item = playerItem else {
                     cShowHUB(superView: nil, msg: "视频获取失败:\(self?.index ?? 0)")
                     cShowHUB(superView: nil, msg: "视频获取失败:\(self?.index ?? 0)")
                     return
                     return
@@ -78,35 +75,33 @@ public class BFRecordItemModel: NSObject {
             })
             })
         }
         }
     }
     }
-    
-    func fetchAVUrlAsset(_ phasset:PHAsset){
+
+    func fetchAVUrlAsset(_ phasset: PHAsset) {
         let options = PHVideoRequestOptions()
         let options = PHVideoRequestOptions()
         options.isNetworkAccessAllowed = true
         options.isNetworkAccessAllowed = true
         options.deliveryMode = .automatic
         options.deliveryMode = .automatic
 
 
-        PHCachingImageManager().requestAVAsset(forVideo: phasset, options: options, resultHandler: {[weak self] (asset: AVAsset?, audioMix: AVAudioMix?, info) in
+        PHCachingImageManager().requestAVAsset(forVideo: phasset, options: options, resultHandler: { [weak self] (asset: AVAsset?, _: AVAudioMix?, _) in
             if let urlAsset = asset as? AVURLAsset {
             if let urlAsset = asset as? AVURLAsset {
                 self?.materialDuraion = urlAsset.duration.seconds
                 self?.materialDuraion = urlAsset.duration.seconds
-                self?.localPath = ((urlAsset.url.absoluteString).removingPercentEncoding)?.replacingOccurrences(of: "file://", with: "")
+                self?.localPath = (urlAsset.url.absoluteString.removingPercentEncoding)?.replacingOccurrences(of: "file://", with: "")
                 self?.fetchAVUrlAsset?(urlAsset)
                 self?.fetchAVUrlAsset?(urlAsset)
             }
             }
         })
         })
     }
     }
-    
-    func generationTimeRanges(needSort:Bool = false) {
-        
+
+    func generationTimeRanges(needSort _: Bool = false) {
         dealedDurationRanges.removeAll()
         dealedDurationRanges.removeAll()
-        
-        var start : Double = 0
-        
+
+        var start: Double = 0
+
         var list: [PQVoiceModel]
         var list: [PQVoiceModel]
         list = voiceStickers.sorted { model1, model2 in
         list = voiceStickers.sorted { model1, model2 in
             model1.startTime < model2.startTime
             model1.startTime < model2.startTime
         }
         }
-        
+
         for model in list {
         for model in list {
-            
-            if model.startTime > start{
+            if model.startTime > start {
                 //
                 //
                 let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), duration: CMTime(seconds: model.startTime - start, preferredTimescale: 100))
                 let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), duration: CMTime(seconds: model.startTime - start, preferredTimescale: 100))
                 dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
                 dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
@@ -121,6 +116,5 @@ public class BFRecordItemModel: NSObject {
             let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), end: CMTime(seconds: materialDuraion, preferredTimescale: 100))
             let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), end: CMTime(seconds: materialDuraion, preferredTimescale: 100))
             dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
             dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
         }
         }
-        
     }
     }
 }
 }

+ 17 - 19
BFRecordScreenKit/Classes/BFVideoThumbImageFetchHelper.swift

@@ -5,44 +5,44 @@
 //  Created by 胡志强 on 2021/12/3.
 //  Created by 胡志强 on 2021/12/3.
 //
 //
 
 
-import Foundation
 import AVFoundation
 import AVFoundation
 import BFCommonKit
 import BFCommonKit
+import Foundation
 
 
 /// 视频分解成帧
 /// 视频分解成帧
 /// - parameter fileUrl                 : 视频地址
 /// - parameter fileUrl                 : 视频地址
 /// - parameter fps                          : 自定义帧数 每秒内取的帧数
 /// - parameter fps                          : 自定义帧数 每秒内取的帧数
 /// - parameter range                     : 获取其中几张连续视频帧
 /// - parameter range                     : 获取其中几张连续视频帧
 /// - parameter splitCompleteClosure    : 回调
 /// - parameter splitCompleteClosure    : 回调
-func splitVideoFileUrlFps(urlAsset:AVURLAsset, fps:Double, range:NSRange? = nil, splitCompleteClosure:@escaping (([UIImage]) -> Void)) {
+func splitVideoFileUrlFps(urlAsset: AVURLAsset, fps: Double, range: NSRange? = nil, splitCompleteClosure: @escaping (([UIImage]) -> Void)) {
     var splitImages = [UIImage]()
     var splitImages = [UIImage]()
-    
+
     var times = [NSValue]()
     var times = [NSValue]()
-    
+
     var start = 0
     var start = 0
     var end = Int(urlAsset.duration.seconds * Float64(fps))
     var end = Int(urlAsset.duration.seconds * Float64(fps))
-    
+
     if range != nil {
     if range != nil {
         start = min(range!.location, end)
         start = min(range!.location, end)
         end = min(start + range!.length, end)
         end = min(start + range!.length, end)
     }
     }
-    
+
     for i in start...end {
     for i in start...end {
-        let timeValue = NSValue(time: CMTimeMake(value: Int64(i * 1000), timescale: Int32(fps * 1000)) )
-        
+        let timeValue = NSValue(time: CMTimeMake(value: Int64(i * 1000), timescale: Int32(fps * 1000)))
+
         times.append(timeValue)
         times.append(timeValue)
     }
     }
-    
+
     let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
     let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
     imgGenerator.requestedTimeToleranceBefore = CMTime.zero
     imgGenerator.requestedTimeToleranceBefore = CMTime.zero
     imgGenerator.requestedTimeToleranceAfter = CMTime.zero
     imgGenerator.requestedTimeToleranceAfter = CMTime.zero
-    
+
     let timesCount = times.count
     let timesCount = times.count
     var cocu = 0
     var cocu = 0
-    //获取每一帧的图片
-    imgGenerator.generateCGImagesAsynchronously(forTimes: times) { (requestedTime, image, actualTime, result, error) in
+    // 获取每一帧的图片
+    imgGenerator.generateCGImagesAsynchronously(forTimes: times) { _, image, _, result, _ in
         cocu += 1
         cocu += 1
-        switch (result) {
+        switch result {
         case AVAssetImageGenerator.Result.cancelled:
         case AVAssetImageGenerator.Result.cancelled:
             BFLog(1, message: "splitVideo: cancel")
             BFLog(1, message: "splitVideo: cancel")
 
 
@@ -56,26 +56,24 @@ func splitVideoFileUrlFps(urlAsset:AVURLAsset, fps:Double, range:NSRange? = nil,
         @unknown default:
         @unknown default:
             break
             break
         }
         }
-        if cocu == timesCount { //最后一帧时 回调赋值
+        if cocu == timesCount { // 最后一帧时 回调赋值
             splitCompleteClosure(splitImages)
             splitCompleteClosure(splitImages)
             BFLog(1, message: "splitVideo: complete")
             BFLog(1, message: "splitVideo: complete")
-
         }
         }
     }
     }
-   
 }
 }
 
 
 /// 视频分解成帧
 /// 视频分解成帧
 /// - parameter fileUrl                 : 视频地址
 /// - parameter fileUrl                 : 视频地址
 /// - parameter fps                     : 自定义帧数 每秒内取的帧数
 /// - parameter fps                     : 自定义帧数 每秒内取的帧数
 /// - parameter splitCompleteClosure    : 回调
 /// - parameter splitCompleteClosure    : 回调
-func getThumbImageAtTime(urlAsset: AVURLAsset, time:CMTime) -> UIImage? {
+func getThumbImageAtTime(urlAsset: AVURLAsset, time: CMTime) -> UIImage? {
     let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
     let imgGenerator = AVAssetImageGenerator(asset: urlAsset)
     imgGenerator.requestedTimeToleranceBefore = CMTime.zero
     imgGenerator.requestedTimeToleranceBefore = CMTime.zero
     imgGenerator.requestedTimeToleranceAfter = CMTime.zero
     imgGenerator.requestedTimeToleranceAfter = CMTime.zero
-    
+
     var cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)
     var cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)
-    if cgImg == nil  {
+    if cgImg == nil {
         imgGenerator.requestedTimeToleranceBefore = CMTime.positiveInfinity
         imgGenerator.requestedTimeToleranceBefore = CMTime.positiveInfinity
         imgGenerator.requestedTimeToleranceAfter = CMTime.positiveInfinity
         imgGenerator.requestedTimeToleranceAfter = CMTime.positiveInfinity
         cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)
         cgImg = try? imgGenerator.copyCGImage(at: time, actualTime: nil)

+ 8 - 10
BFRecordScreenKit/Classes/BFVideoThumbProgressStrategy.swift

@@ -5,30 +5,28 @@
 //  Created by 胡志强 on 2021/12/6.
 //  Created by 胡志强 on 2021/12/6.
 //
 //
 
 
-import Foundation
 import AVFoundation
 import AVFoundation
+import Foundation
 
 
 protocol BFVideoThumbProgressStrategyProtocol {
 protocol BFVideoThumbProgressStrategyProtocol {
-    
     // 根据视频时长获取需要的缩略图数量
     // 根据视频时长获取需要的缩略图数量
     func frameNumberOfVideo(assetDuration: Double) -> Int
     func frameNumberOfVideo(assetDuration: Double) -> Int
 }
 }
 
 
-class BFVideoThumbProgressStrategy : BFVideoThumbProgressStrategyProtocol {
-
+class BFVideoThumbProgressStrategy: BFVideoThumbProgressStrategyProtocol {
     func frameNumberOfVideo(assetDuration: Double) -> Int {
     func frameNumberOfVideo(assetDuration: Double) -> Int {
         var count = -1
         var count = -1
-        
-        if assetDuration > 0 && assetDuration <= 10 {
+
+        if assetDuration > 0, assetDuration <= 10 {
             count = 5
             count = 5
-        }else if assetDuration >= 10 && assetDuration < 60 {
+        } else if assetDuration >= 10, assetDuration < 60 {
             count = 10
             count = 10
-        }else if assetDuration >= 60 && assetDuration < 300 {
+        } else if assetDuration >= 60, assetDuration < 300 {
             count = 20
             count = 20
-        }else if assetDuration >= 300{
+        } else if assetDuration >= 300 {
             count = 30
             count = 30
         }
         }
-        
+
         return count
         return count
     }
     }
 }
 }

+ 21 - 24
BFRecordScreenKit/Classes/BFVoiceRecordManager.swift

@@ -5,26 +5,24 @@
 //  Created by 胡志强 on 2021/11/24.
 //  Created by 胡志强 on 2021/11/24.
 //
 //
 
 
-import Foundation
 import BFCommonKit
 import BFCommonKit
 import BFMediaKit
 import BFMediaKit
+import Foundation
 
 
 class BFVoiceRecordManager {
 class BFVoiceRecordManager {
-    
     // 录音相关
     // 录音相关
     var audioRecorder: NXAudioRecorder?
     var audioRecorder: NXAudioRecorder?
-    var limitedDuration:Double = 600       // 限制录制时长
-    var endRecordHandle : ((PQVoiceModel?, Error?) -> Void)?
-    var cancelRecordHandle : ((Error?) -> Void)?
-
-    var recorderFilePath : String = ""
-    var beginRecordTime:Date = Date()
-    var voiceModel : PQVoiceModel?
-    
+    var limitedDuration: Double = 600 // 限制录制时长
+    var endRecordHandle: ((PQVoiceModel?, Error?) -> Void)?
+    var cancelRecordHandle: ((Error?) -> Void)?
+
+    var recorderFilePath: String = ""
+    var beginRecordTime: Date = Date()
+    var voiceModel: PQVoiceModel?
+
     /// 录制音频。 index初衷是记录录音顺序,废弃了
     /// 录制音频。 index初衷是记录录音顺序,废弃了
     ///
     ///
-    func startRecord(index:Int){
-        
+    func startRecord(index: Int) {
         recorderFilePath = exportAudiosDirectory
         recorderFilePath = exportAudiosDirectory
 
 
         if !directoryIsExists(dicPath: recorderFilePath) {
         if !directoryIsExists(dicPath: recorderFilePath) {
@@ -38,7 +36,7 @@ class BFVoiceRecordManager {
 
 
         } catch {
         } catch {
             BFLog(message: "录音准备失败,当前无法录音 \(error))")
             BFLog(message: "录音准备失败,当前无法录音 \(error))")
-            self.cancelRecordHandle?(error)
+            cancelRecordHandle?(error)
             return
             return
         }
         }
 
 
@@ -57,18 +55,18 @@ class BFVoiceRecordManager {
 
 
 //        beginRecordTime = Date().timeIntervalSince1970
 //        beginRecordTime = Date().timeIntervalSince1970
     }
     }
-    
+
     /// 取消音频录制
     /// 取消音频录制
-    func cancleRecord(){
+    func cancleRecord() {
         stopRecord(isCancel: true)
         stopRecord(isCancel: true)
         cancelRecordHandle?(nil)
         cancelRecordHandle?(nil)
     }
     }
-    
+
     /// 结束音频录制
     /// 结束音频录制
-    func endRecord(){
+    func endRecord() {
         stopRecord(isCancel: false)
         stopRecord(isCancel: false)
     }
     }
-    
+
     // 取所有声音文件的时长
     // 取所有声音文件的时长
     func getAudioFileslDuration() -> Float64 {
     func getAudioFileslDuration() -> Float64 {
         let duration: Float64 = 0.0
         let duration: Float64 = 0.0
@@ -79,7 +77,7 @@ class BFVoiceRecordManager {
 //        }
 //        }
         return duration
         return duration
     }
     }
-    
+
     /// 停止录制 1,正常停止 2,取消停止
     /// 停止录制 1,正常停止 2,取消停止
     /// - Parameter isCancel: 是否为取消
     /// - Parameter isCancel: 是否为取消
     func stopRecord(isCancel: Bool) {
     func stopRecord(isCancel: Bool) {
@@ -91,11 +89,11 @@ class BFVoiceRecordManager {
         audioRecorder?.stopRecord { [weak self] isSuccess, url in
         audioRecorder?.stopRecord { [weak self] isSuccess, url in
             guard let strongSelf = self else { return }
             guard let strongSelf = self else { return }
 
 
-            if strongSelf.getAudioFileslDuration() < 599, (Date().timeIntervalSince( strongSelf.beginRecordTime)) < 1 {
+            if strongSelf.getAudioFileslDuration() < 599, Date().timeIntervalSince(strongSelf.beginRecordTime) < 1 {
                 cShowHUB(superView: nil, msg: "说话时间太短")
                 cShowHUB(superView: nil, msg: "说话时间太短")
             }
             }
 
 
-            let duration = Date().timeIntervalSince( strongSelf.beginRecordTime)
+            let duration = Date().timeIntervalSince(strongSelf.beginRecordTime)
             if isSuccess && !isCancel && duration > 1 {
             if isSuccess && !isCancel && duration > 1 {
                 BFLog(1, message: "结束录音  结果:\(isSuccess) \n url is \(url)")
                 BFLog(1, message: "结束录音  结果:\(isSuccess) \n url is \(url)")
 
 
@@ -103,7 +101,7 @@ class BFVoiceRecordManager {
                 let noiseFilePath = url.replacingOccurrences(of: ".wav", with: "_noise_\(1)_.wav")
                 let noiseFilePath = url.replacingOccurrences(of: ".wav", with: "_noise_\(1)_.wav")
                 BFLog(1, message: "降噪后地址:\(noiseFilePath)")
                 BFLog(1, message: "降噪后地址:\(noiseFilePath)")
                 NXNoiseReduction().denoise(url, outFile: noiseFilePath)
                 NXNoiseReduction().denoise(url, outFile: noiseFilePath)
-                if let model = self?.voiceModel{
+                if let model = self?.voiceModel {
                     model.wavFilePath = noiseFilePath
                     model.wavFilePath = noiseFilePath
                     self?.endRecordHandle?(model, nil)
                     self?.endRecordHandle?(model, nil)
                 }
                 }
@@ -118,11 +116,10 @@ class BFVoiceRecordManager {
                 } catch {
                 } catch {
                     print("Failed to remove recorder file. \(url)")
                     print("Failed to remove recorder file. \(url)")
                 }
                 }
-
             }
             }
-
         }
         }
     }
     }
+
     // 合并 成 MP3文件
     // 合并 成 MP3文件
     func mergeToMP3file() {
     func mergeToMP3file() {
 //        isMergeIng = true
 //        isMergeIng = true

File diff suppressed because it is too large
+ 280 - 304
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift


+ 0 - 1
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenImageController.swift

@@ -10,6 +10,5 @@ import Foundation
 class BFRecordScreenImageController: BFRecordScreenController {
 class BFRecordScreenImageController: BFRecordScreenController {
     override func startRecord() {
     override func startRecord() {
         super.startRecord()
         super.startRecord()
-        
     }
     }
 }
 }

+ 0 - 1
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenVideoController.swift

@@ -10,6 +10,5 @@ import Foundation
 class BFRecordScreenVideoController: BFRecordScreenController {
 class BFRecordScreenVideoController: BFRecordScreenController {
     override func startRecord() {
     override func startRecord() {
         super.startRecord()
         super.startRecord()
-        
     }
     }
 }
 }

+ 12 - 19
BFRecordScreenKit/Classes/RecordScreen/View/BFIntroduceToolView.swift

@@ -9,21 +9,20 @@ import Foundation
 import UIKit
 import UIKit
 
 
 class BFIntroduceToolView: UIView {
 class BFIntroduceToolView: UIView {
-    
-    var choosedToolHandle:((UIView) -> Void)?
-    
+    var choosedToolHandle: ((UIView) -> Void)?
+
     fileprivate let toolImgs = ["", "", ""]
     fileprivate let toolImgs = ["", "", ""]
-    
-    required init?(coder: NSCoder) {
+
+    required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
     }
     }
-    
-    override init(frame: CGRect) {
-        super.init(frame: CGRect(x: 0, y: 0, width: 40, height: 40*toolImgs.count))
+
+    override init(frame _: CGRect) {
+        super.init(frame: CGRect(x: 0, y: 0, width: 40, height: 40 * toolImgs.count))
         isUserInteractionEnabled = true
         isUserInteractionEnabled = true
         clipsToBounds = true
         clipsToBounds = true
-        
-        for i in 0 ..< toolImgs.count {
+
+        for i in 0..<toolImgs.count {
             let btn = UIButton(frame: CGRect(x: 0, y: i * 40, width: 40, height: 40))
             let btn = UIButton(frame: CGRect(x: 0, y: i * 40, width: 40, height: 40))
             btn.backgroundColor = UIColor.randomColor()
             btn.backgroundColor = UIColor.randomColor()
             btn.setTitle("\(i)", for: .normal)
             btn.setTitle("\(i)", for: .normal)
@@ -31,20 +30,14 @@ class BFIntroduceToolView: UIView {
             btn.addTarget(self, action: #selector(toolAction(btn:)), for: .touchUpInside)
             btn.addTarget(self, action: #selector(toolAction(btn:)), for: .touchUpInside)
             addSubview(btn)
             addSubview(btn)
         }
         }
-        
-        
-        
     }
     }
-    
-    @objc func toolAction(btn:UIButton) {
+
+    @objc func toolAction(btn _: UIButton) {
         let v = UILabel(frame: CGRect(x: 0, y: 0, width: 10, height: 40))
         let v = UILabel(frame: CGRect(x: 0, y: 0, width: 10, height: 40))
         v.backgroundColor = UIColor.randomColor()
         v.backgroundColor = UIColor.randomColor()
         v.layer.shadowColor = UIColor.black.cgColor
         v.layer.shadowColor = UIColor.black.cgColor
         v.layer.shadowRadius = 3
         v.layer.shadowRadius = 3
-            
+
         choosedToolHandle?(v)
         choosedToolHandle?(v)
-    
-        
     }
     }
-    
 }
 }

+ 84 - 93
BFRecordScreenKit/Classes/RecordScreen/View/BFRecordAvatarView.swift

@@ -5,104 +5,103 @@
 //  Created by ak on 2021/12/2.
 //  Created by ak on 2021/12/2.
 //  功能:录制头像 ,生成多个 MP4 文件。
 //  功能:录制头像 ,生成多个 MP4 文件。
 
 
-import Foundation
 import BFCommonKit
 import BFCommonKit
 import BFMediaKit
 import BFMediaKit
 import BFUIKit
 import BFUIKit
+import Foundation
 
 
-//录制完成回调
-typealias recordEndCallBack = (_ isSucess: Bool,_ material: PQEditVisionTrackMaterialsModel?) -> Void
+// 录制完成回调
+typealias recordEndCallBack = (_ isSucess: Bool, _ material: PQEditVisionTrackMaterialsModel?) -> Void
 
 
 class BFRecordAvatarView: UIView {
 class BFRecordAvatarView: UIView {
-    
-    //画布
+    // 画布
     var renderView: RenderView!
     var renderView: RenderView!
-    //摄像机
-    var camera:Camera!
-    //是否是录制状态
+    // 摄像机
+    var camera: Camera!
+    // 是否是录制状态
     var isRecording = false
     var isRecording = false
-    //视频输出源
-    var movieOutput:MovieOutput? = nil
-    //录制完成回调
+    // 视频输出源
+    var movieOutput: MovieOutput?
+    // 录制完成回调
     var recordEndCallBack: recordEndCallBack?
     var recordEndCallBack: recordEndCallBack?
-    //录制完成生成的视频文件地址
-    var recorderFilePath:String?
-    //开始录制时间
-    var startRecordeTime:CMTime = .zero
-    
-    //打开摄像头
-    lazy var closedBtn:UIButton = {
+    // 录制完成生成的视频文件地址
+    var recorderFilePath: String?
+    // 开始录制时间
+    var startRecordeTime: CMTime = .zero
+
+    // 打开摄像头
+    lazy var closedBtn: UIButton = {
         let btn = UIButton(type: .custom)
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "CameraClosed"), for: .normal)
         btn.setImage(imageInRecordScreenKit(by: "CameraClosed"), for: .normal)
         btn.addTarget(self, action: #selector(cameraClosed), for: .touchUpInside)
         btn.addTarget(self, action: #selector(cameraClosed), for: .touchUpInside)
         return btn
         return btn
     }()
     }()
-    
-    //预览时纹理大小&合成视频大小
-    var videoPixelsSize:Size = Size(width: 120 * Float(UIScreen.main.scale), height: 120 * Float(UIScreen.main.scale))
-    
+
+    // 预览时纹理大小&合成视频大小
+    var videoPixelsSize: Size = Size(width: 120 * Float(UIScreen.main.scale), height: 120 * Float(UIScreen.main.scale))
+
     override init(frame: CGRect) {
     override init(frame: CGRect) {
         super.init(frame: frame)
         super.init(frame: frame)
-        self.backgroundColor = .yellow
-        
-        renderView = RenderView.init(frame: self.bounds)
+        backgroundColor = .yellow
+
+        renderView = RenderView(frame: bounds)
         addSubview(renderView)
         addSubview(renderView)
-        
-        self.addSubview(closedBtn)
-        closedBtn.frame = CGRect.init(x: frame.maxX - 68, y: frame.maxY - 68, width: 68, height: 68)
+
+        addSubview(closedBtn)
+        closedBtn.frame = CGRect(x: frame.maxX - 68, y: frame.maxY - 68, width: 68, height: 68)
         do {
         do {
-            camera = try Camera(sessionPreset:.high,location: .frontFacing,captureAsYUV: true)
+            camera = try Camera(sessionPreset: .high, location: .frontFacing, captureAsYUV: true)
             //            camera.runBenchmark = true
             //            camera.runBenchmark = true
-           
-            let conertFilter = PQCornerFilter.init()
-            let cropFilter = Crop.init()
+
+            let conertFilter = PQCornerFilter()
+            let cropFilter = Crop()
             cropFilter.cropSizeInPixels = videoPixelsSize
             cropFilter.cropSizeInPixels = videoPixelsSize
-            cropFilter.cropSizeInPixels =  Size(width: 1080, height:1080)
-            cropFilter.locationOfCropInPixels = Position.init(0, (1920 - 1080) / 2)
-            
+            cropFilter.cropSizeInPixels = Size(width: 1080, height: 1080)
+            cropFilter.locationOfCropInPixels = Position(0, (1920 - 1080) / 2)
+
 //            camera  --> cropFilter --> conertFilter --> renderView
 //            camera  --> cropFilter --> conertFilter --> renderView
 //            camera  --> cropFilter --> conertFilter --> renderView
 //            camera  --> cropFilter --> conertFilter --> renderView
         } catch {
         } catch {
             fatalError("Could not initialize rendering pipeline: \(error)")
             fatalError("Could not initialize rendering pipeline: \(error)")
         }
         }
-        
-       let  Drag = UIPanGestureRecognizer(target: self, action: #selector(onDrag(gesture:)))
+
+        let Drag = UIPanGestureRecognizer(target: self, action: #selector(onDrag(gesture:)))
         addGestureRecognizer(Drag)
         addGestureRecognizer(Drag)
     }
     }
-    
+
     required init?(coder _: NSCoder) {
     required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
     }
     }
-    
+
     deinit {
     deinit {
         BFLog(message: "BFRecordAvatarView deinit")
         BFLog(message: "BFRecordAvatarView deinit")
         closeCamera()
         closeCamera()
     }
     }
-    
-    @objc func cameraClosed(){
-        self.isHidden = true
+
+    @objc func cameraClosed() {
+        isHidden = true
         closeCamera()
         closeCamera()
     }
     }
-    
-    //打开摄像头
-    func openCamera()  {
+
+    // 打开摄像头
+    func openCamera() {
         camera.startCapture()
         camera.startCapture()
     }
     }
-    //关闭摄像头
-    func closeCamera()  {
+
+    // 关闭摄像头
+    func closeCamera() {
         camera.stopCapture()
         camera.stopCapture()
     }
     }
-    
-    //开始录制
-    func beginRecord(startTime:CMTime = .zero) {
-        
-        if(!camera.captureSession.isRunning){
+
+    // 开始录制
+    func beginRecord(startTime: CMTime = .zero) {
+        if !camera.captureSession.isRunning {
             BFLog(message: "摄像机不可用")
             BFLog(message: "摄像机不可用")
             return
             return
         }
         }
         startRecordeTime = startTime
         startRecordeTime = startTime
         BFLog(message: "开始录制时间:\(CMTimeGetSeconds(startRecordeTime))")
         BFLog(message: "开始录制时间:\(CMTimeGetSeconds(startRecordeTime))")
-        
+
         do {
         do {
             recorderFilePath = recordVideosDirectory
             recorderFilePath = recordVideosDirectory
             if !directoryIsExists(dicPath: recorderFilePath ?? "") {
             if !directoryIsExists(dicPath: recorderFilePath ?? "") {
@@ -111,40 +110,38 @@ class BFRecordAvatarView: UIView {
             }
             }
             recorderFilePath!.append("recordAvatar_\(Date().timeIntervalSince1970).mp4")
             recorderFilePath!.append("recordAvatar_\(Date().timeIntervalSince1970).mp4")
             BFLog(message: "开始录制视频到: \(recorderFilePath ?? "")")
             BFLog(message: "开始录制视频到: \(recorderFilePath ?? "")")
-            
-            movieOutput = try MovieOutput(URL:URL(fileURLWithPath: recorderFilePath ?? ""), size:videoPixelsSize, liveVideo:true)
-            
-            let cropFilter = Crop.init()
-            let conertFilter = PQCornerFilter.init()
-            
+
+            movieOutput = try MovieOutput(URL: URL(fileURLWithPath: recorderFilePath ?? ""), size: videoPixelsSize, liveVideo: true)
+
+            let cropFilter = Crop()
+            let conertFilter = PQCornerFilter()
+
             cropFilter.cropSizeInPixels = videoPixelsSize
             cropFilter.cropSizeInPixels = videoPixelsSize
-            cropFilter.locationOfCropInPixels = Position.init(0, 0)
-            
-            camera  --> cropFilter --> conertFilter --> movieOutput!
-           
+            cropFilter.locationOfCropInPixels = Position(0, 0)
+
+            camera --> cropFilter --> conertFilter --> movieOutput!
+
             camera.audioEncodingTarget = movieOutput
             camera.audioEncodingTarget = movieOutput
             movieOutput!.startRecording()
             movieOutput!.startRecording()
-            
+
         } catch {
         } catch {
             fatalError("Couldn't initialize movie, error: \(error)")
             fatalError("Couldn't initialize movie, error: \(error)")
         }
         }
-        
     }
     }
-    
-    //结束录制
+
+    // 结束录制
     func endRecord() {
     func endRecord() {
-        
-        movieOutput?.finishRecording{
+        movieOutput?.finishRecording {
             self.camera.audioEncodingTarget = nil
             self.camera.audioEncodingTarget = nil
             self.movieOutput = nil
             self.movieOutput = nil
-            
-            if(self.recorderFilePath != nil && (self.recorderFilePath?.count ?? 0) > 0){
+
+            if self.recorderFilePath != nil && (self.recorderFilePath?.count ?? 0) > 0 {
                 BFLog(message: "录制成功:\(self.recorderFilePath ?? "")")
                 BFLog(message: "录制成功:\(self.recorderFilePath ?? "")")
                 self.recorderFilePath = self.recorderFilePath?.replacingOccurrences(of: documensDirectory, with: "")
                 self.recorderFilePath = self.recorderFilePath?.replacingOccurrences(of: documensDirectory, with: "")
-                
-                //拼接回调 model
+
+                // 拼接回调 model
                 let movieAsset = AVURLAsset(url: URL(fileURLWithPath: self.recorderFilePath!), options: avAssertOptions)
                 let movieAsset = AVURLAsset(url: URL(fileURLWithPath: self.recorderFilePath!), options: avAssertOptions)
-                
+
                 let movieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
                 let movieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
                 movieInfo.type = StickerType.VIDEO.rawValue
                 movieInfo.type = StickerType.VIDEO.rawValue
                 movieInfo.locationPath = self.recorderFilePath ?? ""
                 movieInfo.locationPath = self.recorderFilePath ?? ""
@@ -153,22 +150,20 @@ class BFRecordAvatarView: UIView {
                 movieInfo.model_in = 0
                 movieInfo.model_in = 0
                 movieInfo.out = movieInfo.timelineOut
                 movieInfo.out = movieInfo.timelineOut
                 movieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
                 movieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
-                
-                if(self.recordEndCallBack != nil){
-                    self.recordEndCallBack!(false,movieInfo)
+
+                if self.recordEndCallBack != nil {
+                    self.recordEndCallBack!(false, movieInfo)
                 }
                 }
-                
-            }else{
+
+            } else {
                 BFLog(message: "录制失败:\(self.recorderFilePath ?? "")")
                 BFLog(message: "录制失败:\(self.recorderFilePath ?? "")")
-                if(self.recordEndCallBack != nil){
-                    self.recordEndCallBack!(false,nil)
+                if self.recordEndCallBack != nil {
+                    self.recordEndCallBack!(false, nil)
                 }
                 }
             }
             }
-            
         }
         }
-        
     }
     }
-    
+
 //
 //
 //                let movieAsset = AVURLAsset(url: URL(fileURLWithPath: fileURL), options: avAssertOptions)
 //                let movieAsset = AVURLAsset(url: URL(fileURLWithPath: fileURL), options: avAssertOptions)
 //
 //
@@ -182,21 +177,17 @@ class BFRecordAvatarView: UIView {
 //                movieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
 //                movieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
 //                recordEndCallBack!(movieInfo)
 //                recordEndCallBack!(movieInfo)
 //            }
 //            }
-            
-    
-    //拖拽手势方法具体实现
+
+    // 拖拽手势方法具体实现
     @objc func onDrag(gesture: UIPanGestureRecognizer) {
     @objc func onDrag(gesture: UIPanGestureRecognizer) {
-        let translation = gesture.translation(in: self.superview)
+        let translation = gesture.translation(in: superview)
         var center = gesture.view!.center
         var center = gesture.view!.center
         BFLog(message: "translationtranslationtranslation\(center.x) \(center.y)")
         BFLog(message: "translationtranslationtranslation\(center.x) \(center.y)")
         center.x += translation.x
         center.x += translation.x
         center.y += translation.y
         center.y += translation.y
-        if(center.x > self.bounds.width / 2 && center.x < cScreenWidth - self.bounds.width / 2 && center.y > self.bounds.height / 2 && center.y < cScreenHeigth - self.bounds.height / 2  ){
+        if center.x > bounds.width / 2, center.x < cScreenWidth - bounds.width / 2, center.y > bounds.height / 2, center.y < cScreenHeigth - bounds.height / 2 {
             gesture.view!.center = center
             gesture.view!.center = center
-            gesture.setTranslation(CGPoint.zero, in: self.superview)
+            gesture.setTranslation(CGPoint.zero, in: superview)
         }
         }
-      
-        
     }
     }
-    
 }
 }

+ 25 - 37
BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleEditView.swift

@@ -5,16 +5,16 @@
 //  Created by ak on 2021/12/8.
 //  Created by ak on 2021/12/8.
 //
 //
 
 
-import Foundation
 import BFCommonKit
 import BFCommonKit
-import BFUIKit
 import BFMediaKit
 import BFMediaKit
+import BFUIKit
+import Foundation
 
 
 typealias EditSubtitleDone = (_ text: String) -> Void
 typealias EditSubtitleDone = (_ text: String) -> Void
 
 
 class BFSubtitleEditView: UIView {
 class BFSubtitleEditView: UIView {
-    var editSubtitleDone:EditSubtitleDone?
-    
+    var editSubtitleDone: EditSubtitleDone?
+
 //    var settingModel:BFSubtitileSettingModel = BFSubtitileSettingModel.init()
 //    var settingModel:BFSubtitileSettingModel = BFSubtitileSettingModel.init()
     /// 输入框
     /// 输入框
     lazy var textView: BFTextView = {
     lazy var textView: BFTextView = {
@@ -29,23 +29,21 @@ class BFSubtitleEditView: UIView {
         textView.placeHolderColor = UIColor.hexColor(hexadecimal: "#555555")
         textView.placeHolderColor = UIColor.hexColor(hexadecimal: "#555555")
         textView.delegate = self
         textView.delegate = self
 
 
-        
-        textView.textDidChangedHandle = { [weak self] textView in
-          
+        textView.textDidChangedHandle = { [weak self] _ in
         }
         }
         if #available(iOS 11.0, *) {
         if #available(iOS 11.0, *) {
             textView.contentInsetAdjustmentBehavior = .never
             textView.contentInsetAdjustmentBehavior = .never
         }
         }
         return textView
         return textView
     }()
     }()
-    
-    required init?(coder: NSCoder) {
+
+    required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
-        
     }
     }
+
     override init(frame: CGRect) {
     override init(frame: CGRect) {
-       super.init(frame: frame)
-        backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.7)
+        super.init(frame: frame)
+        backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7)
         addSubview(textView)
         addSubview(textView)
         textView.snp.makeConstraints { make in
         textView.snp.makeConstraints { make in
             make.left.equalTo(37)
             make.left.equalTo(37)
@@ -53,14 +51,13 @@ class BFSubtitleEditView: UIView {
             make.height.equalTo(280)
             make.height.equalTo(280)
             make.top.equalToSuperview().offset(134)
             make.top.equalToSuperview().offset(134)
         }
         }
-        
-        
+
         let doneBtn = UIButton()
         let doneBtn = UIButton()
         doneBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67")
         doneBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67")
         doneBtn.setTitle("完成", for: .normal)
         doneBtn.setTitle("完成", for: .normal)
         doneBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
         doneBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
         doneBtn.addTarget(self, action: #selector(doneAction), for: .touchUpInside)
         doneBtn.addTarget(self, action: #selector(doneAction), for: .touchUpInside)
-        doneBtn.addCorner(corner:4)
+        doneBtn.addCorner(corner: 4)
         addSubview(doneBtn)
         addSubview(doneBtn)
         doneBtn.snp.makeConstraints { make in
         doneBtn.snp.makeConstraints { make in
             make.right.equalTo(-12)
             make.right.equalTo(-12)
@@ -68,7 +65,7 @@ class BFSubtitleEditView: UIView {
             make.height.equalTo(36)
             make.height.equalTo(36)
             make.top.equalToSuperview().offset(48)
             make.top.equalToSuperview().offset(48)
         }
         }
-        
+
         let cancelBtn = UIButton()
         let cancelBtn = UIButton()
         cancelBtn.backgroundColor = .clear
         cancelBtn.backgroundColor = .clear
         cancelBtn.setTitle("取消", for: .normal)
         cancelBtn.setTitle("取消", for: .normal)
@@ -83,43 +80,34 @@ class BFSubtitleEditView: UIView {
             make.top.equalToSuperview().offset(45)
             make.top.equalToSuperview().offset(45)
         }
         }
     }
     }
-    
-    @objc func cancelAction(){
-        self.isHidden = true
+
+    @objc func cancelAction() {
+        isHidden = true
         textView.resignFirstResponder()
         textView.resignFirstResponder()
     }
     }
-    
-    @objc func doneAction(){
-        self.isHidden = true
+
+    @objc func doneAction() {
+        isHidden = true
         textView.resignFirstResponder()
         textView.resignFirstResponder()
-        if(editSubtitleDone != nil){
+        if editSubtitleDone != nil {
             BFLog(message: "最后修改的文字为:\(String(describing: textView.text))")
             BFLog(message: "最后修改的文字为:\(String(describing: textView.text))")
             editSubtitleDone!(textView.text)
             editSubtitleDone!(textView.text)
         }
         }
     }
     }
-    
-    func setNewText(text:String) {
-        
+
+    func setNewText(text: String) {
         textView.text = text.substring(to: 30)
         textView.text = text.substring(to: 30)
 //        BFLog(message: "传值\(textView.text)")
 //        BFLog(message: "传值\(textView.text)")
 //
 //
 //        let attributedText = NSMutableAttributedString(string: textView.text,attributes: [.font: UIFont.systemFont(ofSize: CGFloat(settingModel.subtitleSize)  * 375 / 1080),.strokeWidth:-6,.strokeColor: settingModel.strokeColor,.foregroundColor:settingModel.fontColor])
 //        let attributedText = NSMutableAttributedString(string: textView.text,attributes: [.font: UIFont.systemFont(ofSize: CGFloat(settingModel.subtitleSize)  * 375 / 1080),.strokeWidth:-6,.strokeColor: settingModel.strokeColor,.foregroundColor:settingModel.fontColor])
 //        textView.attributedText = attributedText
 //        textView.attributedText = attributedText
-
-
-        
     }
     }
-
 }
 }
 
 
-extension BFSubtitleEditView: UITextViewDelegate{
-    
-    func textViewDidBeginEditing(_ textView: UITextView) {
-       
-    }
+extension BFSubtitleEditView: UITextViewDelegate {
+    func textViewDidBeginEditing(_: UITextView) {}
 
 
     func textViewDidEndEditing(_ textView: UITextView) {
     func textViewDidEndEditing(_ textView: UITextView) {
-     
         BFLog(message: "textViewDidEndEditing 输入完成 \(textView.text ?? "")")
         BFLog(message: "textViewDidEndEditing 输入完成 \(textView.text ?? "")")
     }
     }
 
 
@@ -129,7 +117,7 @@ extension BFSubtitleEditView: UITextViewDelegate{
             return false
             return false
         }
         }
         BFLog(message: "inputText \(String(describing: textView.text))")
         BFLog(message: "inputText \(String(describing: textView.text))")
- 
+
         return true
         return true
     }
     }
 }
 }

+ 99 - 117
BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleSettingView.swift

@@ -5,41 +5,39 @@
 //  Created by ak on 2021/12/7.
 //  Created by ak on 2021/12/7.
 //  功能:设置字幕操作面板
 //  功能:设置字幕操作面板
 
 
-import Foundation
-import BFMediaKit
 import BFCommonKit
 import BFCommonKit
+import BFMediaKit
 import BFUIKit
 import BFUIKit
+import Foundation
 
 
 typealias SubtitleSettingCallBack = (_ subtitileModel: PQEditSubTitleModel) -> Void
 typealias SubtitleSettingCallBack = (_ subtitileModel: PQEditSubTitleModel) -> Void
 
 
 class BFSubtitleSettingView: UIView {
 class BFSubtitleSettingView: UIView {
-    
-    required init?(coder: NSCoder) {
+    required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
-        
     }
     }
-    
-    //最后一次选择的样式 BTN
-    var lastSelectStyleBtn:UIButton = UIButton.init();
-    //最后一次选择的位置 BTN
-    var lastSelectPointBtn:UIButton = UIButton.init();
-    //最后一次选择的字号的 BTN
-    var lastSelectwordSizeBtn:UIButton = UIButton.init();
-    
-    var subtitleSettingCallBack:SubtitleSettingCallBack?
-    
-    var subtitle:PQEditSubTitleModel = PQEditSubTitleModel.init()
-    
-    //样式配置
-    var styleConfig:Dictionary<Int,Dictionary<String,Any>> = Dictionary.init()
-     
+
+    // 最后一次选择的样式 BTN
+    var lastSelectStyleBtn: UIButton = UIButton()
+    // 最后一次选择的位置 BTN
+    var lastSelectPointBtn: UIButton = UIButton()
+    // 最后一次选择的字号的 BTN
+    var lastSelectwordSizeBtn: UIButton = UIButton()
+
+    var subtitleSettingCallBack: SubtitleSettingCallBack?
+
+    var subtitle: PQEditSubTitleModel = PQEditSubTitleModel()
+
+    // 样式配置
+    var styleConfig: [Int: [String: Any]] = Dictionary()
+
     override init(frame: CGRect) {
     override init(frame: CGRect) {
         super.init(frame: frame)
         super.init(frame: frame)
-        
-        self.backgroundColor = UIColor.clear
+
+        backgroundColor = UIColor.clear
         addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hidden)))
         addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hidden)))
-        
-        let backView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
+
+        let backView = UIView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
         backView.backgroundColor = .black
         backView.backgroundColor = .black
         addSubview(backView)
         addSubview(backView)
         backView.snp.makeConstraints { make in
         backView.snp.makeConstraints { make in
@@ -48,41 +46,37 @@ class BFSubtitleSettingView: UIView {
             make.width.equalTo(cScreenWidth)
             make.width.equalTo(cScreenWidth)
             make.height.equalTo(220)
             make.height.equalTo(220)
         }
         }
- 
-        styleConfig = [0:["fontColor":UIColor.hexColor(hexadecimal:               "#FFCF53"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.black,"backgroundAlpha":0.0],
-                       1:["fontColor":UIColor.hexColor(hexadecimal: "#FF9292"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.black,"backgroundAlpha":0.0],
-                       2:["fontColor":UIColor.hexColor(hexadecimal: "#80C2FF"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.black,"backgroundAlpha":0.0],
-                       3:["fontColor":UIColor.hexColor(hexadecimal: "#80E4AB"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.black,"backgroundAlpha":0.0],
-                       4:["fontColor":UIColor.hexColor(hexadecimal: "#FFFFFF"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.black,"backgroundAlpha":0.0],
-                       5:["fontColor":UIColor.hexColor(hexadecimal: "#000000"),"backgroundColor":UIColor.clear,"strokeColor":UIColor.white,"backgroundAlpha":0.0],
-                     6:["fontColor":UIColor.hexColor(hexadecimal: "#FFFFFF"),"backgroundColor":UIColor.black,"strokeColor":UIColor.black,"backgroundAlpha":0.6]
-        ]
-
-        
-        //字体样式
+
+        styleConfig = [0: ["fontColor": UIColor.hexColor(hexadecimal: "#FFCF53"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.black, "backgroundAlpha": 0.0],
+                       1: ["fontColor": UIColor.hexColor(hexadecimal: "#FF9292"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.black, "backgroundAlpha": 0.0],
+                       2: ["fontColor": UIColor.hexColor(hexadecimal: "#80C2FF"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.black, "backgroundAlpha": 0.0],
+                       3: ["fontColor": UIColor.hexColor(hexadecimal: "#80E4AB"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.black, "backgroundAlpha": 0.0],
+                       4: ["fontColor": UIColor.hexColor(hexadecimal: "#FFFFFF"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.black, "backgroundAlpha": 0.0],
+                       5: ["fontColor": UIColor.hexColor(hexadecimal: "#000000"), "backgroundColor": UIColor.clear, "strokeColor": UIColor.white, "backgroundAlpha": 0.0],
+                       6: ["fontColor": UIColor.hexColor(hexadecimal: "#FFFFFF"), "backgroundColor": UIColor.black, "strokeColor": UIColor.black, "backgroundAlpha": 0.6]]
+
+        // 字体样式
         for i in 0...6 {
         for i in 0...6 {
             let btn = UIButton(type: .custom)
             let btn = UIButton(type: .custom)
             btn.setImage(imageInRecordScreenKit(by: "wordStyle\(i + 1)"), for: .normal)
             btn.setImage(imageInRecordScreenKit(by: "wordStyle\(i + 1)"), for: .normal)
-            btn.setBackgroundImage(UIImage.init(color:.black), for: .normal)
-            btn.frame = CGRect.init(x: 18 + i * ( 40 + 10) , y: 22, width: 40, height: 40)
+            btn.setBackgroundImage(UIImage(color: .black), for: .normal)
+            btn.frame = CGRect(x: 18 + i * (40 + 10), y: 22, width: 40, height: 40)
             btn.tag = i
             btn.tag = i
-            if(i == 0){
+            if i == 0 {
                 btn.isSelected = true
                 btn.isSelected = true
                 btn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 btn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 btn.layer.borderWidth = 1.5
                 btn.layer.borderWidth = 1.5
                 lastSelectStyleBtn = btn
                 lastSelectStyleBtn = btn
-                
+
                 styleSetting(sender: lastSelectStyleBtn)
                 styleSetting(sender: lastSelectStyleBtn)
-                
             }
             }
-        
+
             btn.addTarget(self, action: #selector(styleSetting(sender:)), for: .touchUpInside)
             btn.addTarget(self, action: #selector(styleSetting(sender:)), for: .touchUpInside)
             backView.addSubview(btn)
             backView.addSubview(btn)
             btn.addCorner(corner: 20.0)
             btn.addCorner(corner: 20.0)
-
         }
         }
-        
-        //位置
+
+        // 位置
         let pointTitle = UILabel()
         let pointTitle = UILabel()
         pointTitle.textAlignment = .center
         pointTitle.textAlignment = .center
         pointTitle.font = UIFont.systemFont(ofSize: 15)
         pointTitle.font = UIFont.systemFont(ofSize: 15)
@@ -96,38 +90,36 @@ class BFSubtitleSettingView: UIView {
             make.left.equalToSuperview().offset(16)
             make.left.equalToSuperview().offset(16)
             make.top.equalToSuperview().offset(89)
             make.top.equalToSuperview().offset(89)
         }
         }
-        for i  in 0...2 {
+        for i in 0...2 {
             let pointBtn = UIButton(type: .custom)
             let pointBtn = UIButton(type: .custom)
             pointBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#28BE67"), for: .selected)
             pointBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#28BE67"), for: .selected)
             pointBtn.setTitleColor(.white, for: .normal)
             pointBtn.setTitleColor(.white, for: .normal)
             pointBtn.addTarget(self, action: #selector(pointSetting(sender:)), for: .touchUpInside)
             pointBtn.addTarget(self, action: #selector(pointSetting(sender:)), for: .touchUpInside)
             pointBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
             pointBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
-            if(i == 0){
+            if i == 0 {
                 pointBtn.isSelected = true
                 pointBtn.isSelected = true
                 pointBtn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 pointBtn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 pointBtn.layer.borderWidth = 1.5
                 pointBtn.layer.borderWidth = 1.5
                 lastSelectPointBtn = pointBtn
                 lastSelectPointBtn = pointBtn
                 pointBtn.setTitle("下", for: .normal)
                 pointBtn.setTitle("下", for: .normal)
-            }else if(i == 1){
+            } else if i == 1 {
                 pointBtn.setTitle("中", for: .normal)
                 pointBtn.setTitle("中", for: .normal)
-            }else{
+            } else {
                 pointBtn.setTitle("上", for: .normal)
                 pointBtn.setTitle("上", for: .normal)
             }
             }
-            pointBtn.addCorner(corner:10)
+            pointBtn.addCorner(corner: 10)
             pointBtn.tag = i
             pointBtn.tag = i
             backView.addSubview(pointBtn)
             backView.addSubview(pointBtn)
             pointBtn.snp.makeConstraints { make in
             pointBtn.snp.makeConstraints { make in
                 make.width.equalTo(40)
                 make.width.equalTo(40)
                 make.height.equalTo(30)
                 make.height.equalTo(30)
-                make.centerX.equalTo(pointTitle.snp.centerX).offset(60 + i * (Int(40  + 10)))
-                
+                make.centerX.equalTo(pointTitle.snp.centerX).offset(60 + i * Int(40 + 10))
+
                 make.centerY.equalTo(pointTitle.snp.centerY)
                 make.centerY.equalTo(pointTitle.snp.centerY)
             }
             }
-            
-            
         }
         }
-        
-        //字号
+
+        // 字号
         let wordSizeTitle = UILabel()
         let wordSizeTitle = UILabel()
         wordSizeTitle.textAlignment = .center
         wordSizeTitle.textAlignment = .center
         wordSizeTitle.font = UIFont.systemFont(ofSize: 15)
         wordSizeTitle.font = UIFont.systemFont(ofSize: 15)
@@ -141,7 +133,7 @@ class BFSubtitleSettingView: UIView {
             make.right.equalToSuperview().offset(-100)
             make.right.equalToSuperview().offset(-100)
             make.top.equalTo(pointTitle.snp.top)
             make.top.equalTo(pointTitle.snp.top)
         }
         }
-        for i  in 0...1 {
+        for i in 0...1 {
             let wordSizeBtn = UIButton(type: .custom)
             let wordSizeBtn = UIButton(type: .custom)
             wordSizeBtn.addTarget(self, action: #selector(wordSizeSetting(sender:)), for: .touchUpInside)
             wordSizeBtn.addTarget(self, action: #selector(wordSizeSetting(sender:)), for: .touchUpInside)
             wordSizeBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
             wordSizeBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
@@ -150,36 +142,34 @@ class BFSubtitleSettingView: UIView {
             wordSizeBtn.setTitle(i == 0 ? "-" : "+", for: .normal)
             wordSizeBtn.setTitle(i == 0 ? "-" : "+", for: .normal)
             backView.addSubview(wordSizeBtn)
             backView.addSubview(wordSizeBtn)
             wordSizeBtn.tag = i
             wordSizeBtn.tag = i
-            if(i == 0){
+            if i == 0 {
                 wordSizeBtn.isSelected = true
                 wordSizeBtn.isSelected = true
                 wordSizeBtn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 wordSizeBtn.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
                 wordSizeBtn.layer.borderWidth = 1.5
                 wordSizeBtn.layer.borderWidth = 1.5
                 lastSelectwordSizeBtn = wordSizeBtn
                 lastSelectwordSizeBtn = wordSizeBtn
             }
             }
-            wordSizeBtn.addCorner(corner:10)
+            wordSizeBtn.addCorner(corner: 10)
             wordSizeBtn.snp.makeConstraints { make in
             wordSizeBtn.snp.makeConstraints { make in
                 make.width.equalTo(30)
                 make.width.equalTo(30)
                 make.height.equalTo(30)
                 make.height.equalTo(30)
-                make.left.equalTo(wordSizeTitle.snp.right).offset( 10 + i * (Int(30  + 10)))
-                
+                make.left.equalTo(wordSizeTitle.snp.right).offset(10 + i * Int(30 + 10))
+
                 make.centerY.equalTo(pointTitle.snp.centerY)
                 make.centerY.equalTo(pointTitle.snp.centerY)
             }
             }
-            
-            
         }
         }
-        //就是一个线
-        let line = UIView.init()
-        line.backgroundColor =  UIColor.hexColor(hexadecimal: "#121212")
+        // 就是一个线
+        let line = UIView()
+        line.backgroundColor = UIColor.hexColor(hexadecimal: "#121212")
         backView.addSubview(line)
         backView.addSubview(line)
-        
+
         line.snp.makeConstraints { make in
         line.snp.makeConstraints { make in
             make.width.equalTo(340)
             make.width.equalTo(340)
             make.height.equalTo(2)
             make.height.equalTo(2)
             make.left.equalToSuperview().offset(18)
             make.left.equalToSuperview().offset(18)
             make.top.equalTo(wordSizeTitle.snp.bottom).offset(23)
             make.top.equalTo(wordSizeTitle.snp.bottom).offset(23)
         }
         }
-        
-        //不显示字幕
+
+        // 不显示字幕
         let disabelTitle = UILabel()
         let disabelTitle = UILabel()
         disabelTitle.textAlignment = .left
         disabelTitle.textAlignment = .left
         disabelTitle.font = UIFont.boldSystemFont(ofSize: 17)
         disabelTitle.font = UIFont.boldSystemFont(ofSize: 17)
@@ -203,94 +193,86 @@ class BFSubtitleSettingView: UIView {
             make.right.equalToSuperview().offset(-18)
             make.right.equalToSuperview().offset(-18)
             make.top.equalTo(line.snp.top).offset(13)
             make.top.equalTo(line.snp.top).offset(13)
         }
         }
-     
-        
-        
+
         //        addCorner(roundingCorners: .topLeft, corner: 10)
         //        addCorner(roundingCorners: .topLeft, corner: 10)
         //        addCorner(roundingCorners: .topRight, corner: 10)
         //        addCorner(roundingCorners: .topRight, corner: 10)
         BFLog(message: "")
         BFLog(message: "")
-        
     }
     }
-    
-    @objc func hidden(){
-        self.isHidden = true
+
+    @objc func hidden() {
+        isHidden = true
     }
     }
-    
-    @objc func styleSetting(sender: UIButton){
+
+    @objc func styleSetting(sender: UIButton) {
         lastSelectStyleBtn.isSelected = false
         lastSelectStyleBtn.isSelected = false
         lastSelectStyleBtn.layer.borderColor = UIColor.clear.cgColor
         lastSelectStyleBtn.layer.borderColor = UIColor.clear.cgColor
-        
+
         sender.isSelected = true
         sender.isSelected = true
         lastSelectStyleBtn = sender
         lastSelectStyleBtn = sender
-        
+
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderWidth = 1.5
         sender.layer.borderWidth = 1.5
-        
+
         subtitle.setting.subtitleStyle = sender.tag
         subtitle.setting.subtitleStyle = sender.tag
-        
+
         let config = styleConfig[sender.tag]
         let config = styleConfig[sender.tag]
-        
+
         subtitle.setting.fontColor = config?["fontColor"] as! UIColor
         subtitle.setting.fontColor = config?["fontColor"] as! UIColor
         subtitle.setting.backgroundColor = config?["backgroundColor"] as! UIColor
         subtitle.setting.backgroundColor = config?["backgroundColor"] as! UIColor
         subtitle.setting.backgroundAlpha = Float(config?["backgroundAlpha"] as! Double)
         subtitle.setting.backgroundAlpha = Float(config?["backgroundAlpha"] as! Double)
         subtitle.setting.strokeColor = config?["strokeColor"] as! UIColor
         subtitle.setting.strokeColor = config?["strokeColor"] as! UIColor
- 
-        if(subtitleSettingCallBack != nil){
+
+        if subtitleSettingCallBack != nil {
             subtitleSettingCallBack!(subtitle)
             subtitleSettingCallBack!(subtitle)
         }
         }
-     
     }
     }
-    @objc func pointSetting(sender:UIButton){
-        
+
+    @objc func pointSetting(sender: UIButton) {
         lastSelectPointBtn.isSelected = false
         lastSelectPointBtn.isSelected = false
         lastSelectPointBtn.layer.borderColor = UIColor.clear.cgColor
         lastSelectPointBtn.layer.borderColor = UIColor.clear.cgColor
-        
+
         sender.isSelected = true
         sender.isSelected = true
         lastSelectPointBtn = sender
         lastSelectPointBtn = sender
-        
+
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderWidth = 1.5
         sender.layer.borderWidth = 1.5
-        
+
         subtitle.setting.subtitlePoint = sender.tag
         subtitle.setting.subtitlePoint = sender.tag
-    
-        if(subtitleSettingCallBack != nil){
+
+        if subtitleSettingCallBack != nil {
             subtitleSettingCallBack!(subtitle)
             subtitleSettingCallBack!(subtitle)
         }
         }
     }
     }
-    @objc func wordSizeSetting(sender:UIButton){
-     
+
+    @objc func wordSizeSetting(sender: UIButton) {
         lastSelectwordSizeBtn.isSelected = false
         lastSelectwordSizeBtn.isSelected = false
         lastSelectwordSizeBtn.layer.borderColor = UIColor.clear.cgColor
         lastSelectwordSizeBtn.layer.borderColor = UIColor.clear.cgColor
-        
+
         sender.isSelected = true
         sender.isSelected = true
         lastSelectwordSizeBtn = sender
         lastSelectwordSizeBtn = sender
-        
+
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderColor = UIColor.hexColor(hexadecimal: "#28BE67").cgColor
         sender.layer.borderWidth = 1.5
         sender.layer.borderWidth = 1.5
 
 
-            if(sender.tag == 0 && subtitle.setting.subtitleSize > 20){
-                subtitle.setting.subtitleSize -= 10
-            }else if(sender.tag == 1 && subtitle.setting.subtitleSize < 120){
-                subtitle.setting.subtitleSize += 10
-            }else{
-                BFLog(message: "设置字号超出范围!")
-            }
-            if(subtitleSettingCallBack != nil){
-                subtitleSettingCallBack!(subtitle)
-            }
-            
-        
-   
+        if sender.tag == 0, subtitle.setting.subtitleSize > 20 {
+            subtitle.setting.subtitleSize -= 10
+        } else if sender.tag == 1, subtitle.setting.subtitleSize < 120 {
+            subtitle.setting.subtitleSize += 10
+        } else {
+            BFLog(message: "设置字号超出范围!")
+        }
+        if subtitleSettingCallBack != nil {
+            subtitleSettingCallBack!(subtitle)
+        }
     }
     }
-    @objc func switchChange(uiswitch:UISwitch) {
-        print("字幕开关状态\(uiswitch.isOn )")
-        
+
+    @objc func switchChange(uiswitch: UISwitch) {
+        print("字幕开关状态\(uiswitch.isOn)")
+
         subtitle.setting.subtitleIsShow = !uiswitch.isOn
         subtitle.setting.subtitleIsShow = !uiswitch.isOn
-        
-        if(subtitleSettingCallBack != nil){
+
+        if subtitleSettingCallBack != nil {
             subtitleSettingCallBack!(subtitle)
             subtitleSettingCallBack!(subtitle)
         }
         }
     }
     }
 }
 }
-
-

+ 46 - 50
BFRecordScreenKit/Classes/RecordScreen/View/BFVideoThumbProgressView.swift

@@ -5,26 +5,26 @@
 //  Created by 胡志强 on 2021/12/3.
 //  Created by 胡志强 on 2021/12/3.
 //
 //
 
 
-import Foundation
-import UIKit
 import AVFoundation
 import AVFoundation
 import BFCommonKit
 import BFCommonKit
-import SnapKit
 import BFUIKit
 import BFUIKit
+import Foundation
+import SnapKit
+import UIKit
 
 
 class BFVideoThumbProgressView: UIView {
 class BFVideoThumbProgressView: UIView {
-    var videoAsset : AVURLAsset? {
-        didSet{
+    var videoAsset: AVURLAsset? {
+        didSet {
             if let videoAsset = videoAsset {
             if let videoAsset = videoAsset {
                 let dur = videoAsset.duration.seconds
                 let dur = videoAsset.duration.seconds
-                if dur > 0{
+                if dur > 0 {
                     let fps = Double(fetchThumbStrategy.frameNumberOfVideo(assetDuration: dur)) / dur
                     let fps = Double(fetchThumbStrategy.frameNumberOfVideo(assetDuration: dur)) / dur
-                    
-                    splitVideoFileUrlFps(urlAsset: videoAsset, fps: fps) {[weak self] images in
-                        if images.count > 0{
+
+                    splitVideoFileUrlFps(urlAsset: videoAsset, fps: fps) { [weak self] images in
+                        if images.count > 0 {
                             self?.thumbImgs = images
                             self?.thumbImgs = images
-                            DispatchQueue.main.async {[weak self] in
-                                if let sself = self{
+                            DispatchQueue.main.async { [weak self] in
+                                if let sself = self {
                                     var lastiv = UIImageView()
                                     var lastiv = UIImageView()
                                     for (i, img) in images.enumerated() {
                                     for (i, img) in images.enumerated() {
                                         let iv = UIImageView(image: img)
                                         let iv = UIImageView(image: img)
@@ -42,7 +42,7 @@ class BFVideoThumbProgressView: UIView {
                                     lastiv.snp.makeConstraints { make in
                                     lastiv.snp.makeConstraints { make in
                                         make.right.equalTo(sself.width * -0.5)
                                         make.right.equalTo(sself.width * -0.5)
                                     }
                                     }
-                                    
+
                                     sself.progressView.contentView.addSubview(sself.progessIndicateBackV)
                                     sself.progressView.contentView.addSubview(sself.progessIndicateBackV)
                                     sself.progessIndicateBackV.snp.makeConstraints { make in
                                     sself.progessIndicateBackV.snp.makeConstraints { make in
                                         make.left.equalTo(sself.width * 0.5)
                                         make.left.equalTo(sself.width * 0.5)
@@ -54,49 +54,48 @@ class BFVideoThumbProgressView: UIView {
                             }
                             }
                         }
                         }
                     }
                     }
-                    
                 }
                 }
             }
             }
         }
         }
     }
     }
-    
-    var dragScrollProgressHandle : ((Bool, Float) -> Void)?
-    var dragEndHandle : ((Float) -> Void)?
-    var dragStartHandle : (() -> Void)?
+
+    var dragScrollProgressHandle: ((Bool, Float) -> Void)?
+    var dragEndHandle: ((Float) -> Void)?
+    var dragStartHandle: (() -> Void)?
     var isDrag = false
     var isDrag = false
-    
+
     let thumbImageWidth = 70.0
     let thumbImageWidth = 70.0
-    
-    let fetchThumbStrategy : BFVideoThumbProgressStrategyProtocol = BFVideoThumbProgressStrategy()
-    
-    var progress:Double = 0 {
-        didSet{
-            if let second = self.videoAsset?.duration.seconds, second > 0 {
+
+    let fetchThumbStrategy: BFVideoThumbProgressStrategyProtocol = BFVideoThumbProgressStrategy()
+
+    var progress: Double = 0 {
+        didSet {
+            if let second = videoAsset?.duration.seconds, second > 0 {
                 let w = progressView.contentSize.width - width
                 let w = progressView.contentSize.width - width
                 progressView.contentOffset = CGPoint(x: progress * Double(w) / second, y: 0)
                 progressView.contentOffset = CGPoint(x: progress * Double(w) / second, y: 0)
             }
             }
         }
         }
     }
     }
-    
+
     var thumbImgs = [UIImage]()
     var thumbImgs = [UIImage]()
-    
-    lazy var progressView : BFAutolayoutScrollView = {
+
+    lazy var progressView: BFAutolayoutScrollView = {
         let sv = BFAutolayoutScrollView()
         let sv = BFAutolayoutScrollView()
         sv.bounces = false
         sv.bounces = false
         sv.backgroundColor = .clear
         sv.backgroundColor = .clear
         sv.decelerationRate = .fast
         sv.decelerationRate = .fast
         sv.showsHorizontalScrollIndicator = false
         sv.showsHorizontalScrollIndicator = false
         sv.delegate = self
         sv.delegate = self
-        
+
         return sv
         return sv
     }()
     }()
-    
-    lazy var progessIndicateBackV : UIView = {
+
+    lazy var progessIndicateBackV: UIView = {
         let vv = UIView()
         let vv = UIView()
         return vv
         return vv
     }()
     }()
-    
-    //MARK: - 生命周期
+
+    // MARK: - 生命周期
 
 
     override init(frame: CGRect) {
     override init(frame: CGRect) {
         super.init(frame: frame)
         super.init(frame: frame)
@@ -112,50 +111,47 @@ class BFVideoThumbProgressView: UIView {
             make.width.equalTo(3)
             make.width.equalTo(3)
             make.center.height.equalToSuperview()
             make.center.height.equalToSuperview()
         }
         }
-        
     }
     }
 
 
-    required init?(coder: NSCoder) {
+    required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
     }
     }
-    
+
     override func layoutSubviews() {
     override func layoutSubviews() {
         super.layoutSubviews()
         super.layoutSubviews()
-        
+
         progressView.snp.makeConstraints { make in
         progressView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
             make.edges.equalToSuperview()
         }
         }
-        
     }
     }
 }
 }
 
 
-extension BFVideoThumbProgressView : UIScrollViewDelegate {
+extension BFVideoThumbProgressView: UIScrollViewDelegate {
     func scrollViewDidScroll(_ scrollView: UIScrollView) {
     func scrollViewDidScroll(_ scrollView: UIScrollView) {
-        if isDrag{
-            let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - self.width)
-            self.dragScrollProgressHandle?(false, Float(dur))
+        if isDrag {
+            let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - width)
+            dragScrollProgressHandle?(false, Float(dur))
         }
         }
     }
     }
-    
+
     func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
     func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
         isDrag = true
         isDrag = true
-        let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - self.width)
-        self.dragStartHandle?()
-        self.dragScrollProgressHandle?(true, Float(dur))
+        let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - width)
+        dragStartHandle?()
+        dragScrollProgressHandle?(true, Float(dur))
     }
     }
-    
+
     func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
     func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
         if !decelerate {
         if !decelerate {
-            let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - self.width)
+            let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - width)
             isDrag = false
             isDrag = false
             dragEndHandle?(Float(dur))
             dragEndHandle?(Float(dur))
         }
         }
     }
     }
-    
+
     func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
     func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - self.width)
+        let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - width)
         isDrag = false
         isDrag = false
         dragEndHandle?(Float(dur))
         dragEndHandle?(Float(dur))
     }
     }
-    
 }
 }

+ 18 - 23
BFRecordScreenKit/Classes/RecordScreen/ViewModel/BFRecordScreenViewModel.swift

@@ -5,18 +5,17 @@
 //  Created by ak on 2021/12/7.
 //  Created by ak on 2021/12/7.
 //
 //
 
 
-import Foundation
+import BFCommonKit
 import BFMediaKit
 import BFMediaKit
+import BFNetRequestKit
+import Foundation
 import ObjectMapper
 import ObjectMapper
 import RealmSwift
 import RealmSwift
-import BFCommonKit
-import BFNetRequestKit
 
 
-public class BFRecordScreenViewModel:NSObject{
-   
+public class BFRecordScreenViewModel: NSObject {
     /// 取文本转语言 token
     /// 取文本转语言 token
     /// - Parameter completeHander: <#completeHander description#>
     /// - Parameter completeHander: <#completeHander description#>
-    class public func getNlsAccessToken(completeHander: @escaping (_ token: String, _ appkey:String) -> Void) {
+    public class func getNlsAccessToken(completeHander: @escaping (_ token: String, _ appkey: String) -> Void) {
         let NlsAccessTokenKey: String = "NlsAccessTokenKey_JiangjieApp"
         let NlsAccessTokenKey: String = "NlsAccessTokenKey_JiangjieApp"
 
 
         let nowTime: TimeInterval = Date().timeIntervalSince1970
         let nowTime: TimeInterval = Date().timeIntervalSince1970
@@ -26,39 +25,36 @@ public class BFRecordScreenViewModel:NSObject{
         let saveToken: Dictionary? = getUserDefaults(key: NlsAccessTokenKey) as? [String: Any] ?? nil
         let saveToken: Dictionary? = getUserDefaults(key: NlsAccessTokenKey) as? [String: Any] ?? nil
         if saveToken != nil && Double(saveToken!["expireTime"] as! Double) > nowTime * 1000 {
         if saveToken != nil && Double(saveToken!["expireTime"] as! Double) > nowTime * 1000 {
             BFLog(message: "nls token 还有效期内不用重新请求 \(String(describing: saveToken!["expireTime"])) nowTime:\(nowTime * 1000)")
             BFLog(message: "nls token 还有效期内不用重新请求 \(String(describing: saveToken!["expireTime"])) nowTime:\(nowTime * 1000)")
-            completeHander(saveToken!["token"] as! String,saveToken!["appkey"] as! String)
+            completeHander(saveToken!["token"] as! String, saveToken!["appkey"] as! String)
             return
             return
         }
         }
         BFNetRequestAdaptor.getRequestData(url: PQENVUtil.shared.clipapiapi + getNlsAccessTokenForJiangjieApp, parames: nil, commonParams: commonParams()) { response, _, _, _ in
         BFNetRequestAdaptor.getRequestData(url: PQENVUtil.shared.clipapiapi + getNlsAccessTokenForJiangjieApp, parames: nil, commonParams: commonParams()) { response, _, _, _ in
 
 
-            if let response = response as? [String: Any], let token = response["token"] as? String , let appkey = response["appkey"] as? String {
+            if let response = response as? [String: Any], let token = response["token"] as? String, let appkey = response["appkey"] as? String {
                 let nowTime: TimeInterval = Date().timeIntervalSince1970
                 let nowTime: TimeInterval = Date().timeIntervalSince1970
 
 
                 BFLog(message: "nowTime is \(nowTime) token is \(token)")
                 BFLog(message: "nowTime is \(nowTime) token is \(token)")
                 saveUserDefaults(key: NlsAccessTokenKey, value: response)
                 saveUserDefaults(key: NlsAccessTokenKey, value: response)
 
 
-                completeHander(token,appkey)
+                completeHander(token, appkey)
             } else {
             } else {
-                completeHander("","")
+                completeHander("", "")
             }
             }
         }
         }
     }
     }
-    
-    
+
     /// 分段识别录音
     /// 分段识别录音
     /// - Parameters:
     /// - Parameters:
     ///   - sectionIndex: 段落id
     ///   - sectionIndex: 段落id
     ///   - locationPaths: 分段录音
     ///   - locationPaths: 分段录音
     ///   - completeHander: <#completeHander description#>
     ///   - completeHander: <#completeHander description#>
     /// - Returns: description
     /// - Returns: description
-    class public func batchUploadRecordVoiceMatarialData(beginTime: CMTime, locationPath: String, completeHander: @escaping (_ subTitleList: List<PQEditVisionTrackMaterialsModel>?, _ msg: String?) -> Void) {
-      
+    public class func batchUploadRecordVoiceMatarialData(beginTime _: CMTime, locationPath: String, completeHander _: @escaping (_ subTitleList: List<PQEditVisionTrackMaterialsModel>?, _ msg: String?) -> Void) {
         BFLog(message: "录音文件开始上传--\(locationPath)")
         BFLog(message: "录音文件开始上传--\(locationPath)")
-     
-        if !FileManager.default.fileExists(atPath:documensDirectory + locationPath) {
+
+        if !FileManager.default.fileExists(atPath: documensDirectory + locationPath) {
             BFLog(message: "上传录音-录音文件不存在")
             BFLog(message: "上传录音-录音文件不存在")
         } else {
         } else {
-
             let assert = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + locationPath), options: nil)
             let assert = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + locationPath), options: nil)
             let voiceMaterials: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
             let voiceMaterials: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
             voiceMaterials.locationPath = locationPath
             voiceMaterials.locationPath = locationPath
@@ -68,7 +64,7 @@ public class BFRecordScreenViewModel:NSObject{
 //            PQVideoEditViewModel.uploadMatarialData(isBatchUpload: false, materialData: voiceMaterials) { _, _, _, _, _, _, matarialInfo, _ in
 //            PQVideoEditViewModel.uploadMatarialData(isBatchUpload: false, materialData: voiceMaterials) { _, _, _, _, _, _, matarialInfo, _ in
 //                let materialType: String = "\(matarialInfo?["materialType"] ?? "")"
 //                let materialType: String = "\(matarialInfo?["materialType"] ?? "")"
 //                let localPath: String = "\(matarialInfo?["localPath"] ?? "")"
 //                let localPath: String = "\(matarialInfo?["localPath"] ?? "")"
-//                
+//
 //                BFLog(message: "上传录音-录音上传返回--\(String(describing: matarialInfo))")
 //                BFLog(message: "上传录音-录音上传返回--\(String(describing: matarialInfo))")
 //                if matarialInfo != nil, matarialInfo?.keys.contains("localPath") ?? false, materialType == StickerType.VOICE.rawValue && localPath.contains("_noise_") {
 //                if matarialInfo != nil, matarialInfo?.keys.contains("localPath") ?? false, materialType == StickerType.VOICE.rawValue && localPath.contains("_noise_") {
 //                    BFLog(message: "上传录音-录音上传成功开始转化字幕")
 //                    BFLog(message: "上传录音-录音上传成功开始转化字幕")
@@ -76,16 +72,16 @@ public class BFRecordScreenViewModel:NSObject{
 //                    let duration: Float64 = Float64("\(matarialInfo?["duration"] ?? "")") ?? 0
 //                    let duration: Float64 = Float64("\(matarialInfo?["duration"] ?? "")") ?? 0
 //                    PQVideoEditViewModel.transferAudioMaterialToTextData(Int64(materialId) ?? 0, dutation: duration) { _, _, subTitleList, _ in
 //                    PQVideoEditViewModel.transferAudioMaterialToTextData(Int64(materialId) ?? 0, dutation: duration) { _, _, subTitleList, _ in
 //                        BFLog(message: "上传录音-字幕转化完成:\(subTitleList.count)")
 //                        BFLog(message: "上传录音-字幕转化完成:\(subTitleList.count)")
-// 
+//
 //                        if subTitleList.count > 0 {
 //                        if subTitleList.count > 0 {
-//                    
+//
 //                        }
 //                        }
-//                
+//
 //                    }
 //                    }
 //                }
 //                }
 //            }
 //            }
         }
         }
-        
+
         //        dispatchGroup.notify(queue: DispatchQueue.main) {
         //        dispatchGroup.notify(queue: DispatchQueue.main) {
         //            BFLog(message: "语音均已识别完成")
         //            BFLog(message: "语音均已识别完成")
         //            let subTitleList: List<PQEditVisionTrackMaterialsModel> = List<PQEditVisionTrackMaterialsModel>.init()
         //            let subTitleList: List<PQEditVisionTrackMaterialsModel> = List<PQEditVisionTrackMaterialsModel>.init()
@@ -98,5 +94,4 @@ public class BFRecordScreenViewModel:NSObject{
         //            completeHander(sectionIndex, subTitleList, nil)
         //            completeHander(sectionIndex, subTitleList, nil)
         //        }
         //        }
     }
     }
-    
 }
 }

+ 11 - 16
Example/BFRecordScreenKit/AppDelegate.swift

@@ -6,17 +6,15 @@
 //  Copyright (c) 2021 harry. All rights reserved.
 //  Copyright (c) 2021 harry. All rights reserved.
 //
 //
 
 
-import UIKit
-import BFMaterialKit
 import BFCommonKit
 import BFCommonKit
+import BFMaterialKit
+import UIKit
 
 
 @UIApplicationMain
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
 class AppDelegate: UIResponder, UIApplicationDelegate {
-
     var window: UIWindow?
     var window: UIWindow?
 
 
-
-    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+    func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
         // Override point for customization after application launch.
         // Override point for customization after application launch.
         BFConfig.shared.styleColor = .nomal
         BFConfig.shared.styleColor = .nomal
         BFConfig.shared.statusBarStyle = .light
         BFConfig.shared.statusBarStyle = .light
@@ -25,18 +23,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         BFConfig.shared.cutViewStyleColor = UIColor.white
         BFConfig.shared.cutViewStyleColor = UIColor.white
         BFConfig.shared.cutViewTintColor = UIColor.black
         BFConfig.shared.cutViewTintColor = UIColor.black
         BFConfig.shared.pointEditNamalBackgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
         BFConfig.shared.pointEditNamalBackgroundColor = UIColor.hexColor(hexadecimal: "#1A1A1A")
-        BFMaterialConfig.shared.materialDeleteImage =  UIImage.moduleImage(named: "icon_search_delete", moduleName: "BFMaterialKit") ?? UIImage.init()
+        BFMaterialConfig.shared.materialDeleteImage = UIImage.moduleImage(named: "icon_search_delete", moduleName: "BFMaterialKit") ?? UIImage()
         BFConfig.shared.cutDurationColor = UIColor(red: 238.0 / 255.0, green: 0 / 255.0, blue: 81.0 / 255.0, alpha: 0.1)
         BFConfig.shared.cutDurationColor = UIColor(red: 238.0 / 255.0, green: 0 / 255.0, blue: 81.0 / 255.0, alpha: 0.1)
         BFConfig.shared.hiddenMusicMask = false
         BFConfig.shared.hiddenMusicMask = false
         BFConfig.shared.otherTintColor = UIColor.hexColor(hexadecimal: "#333333")
         BFConfig.shared.otherTintColor = UIColor.hexColor(hexadecimal: "#333333")
         BFConfig.shared.statusBarStyle = .light
         BFConfig.shared.statusBarStyle = .light
         BFMaterialConfig.shared.choseType = .single
         BFMaterialConfig.shared.choseType = .single
-        if let tbc = self.window?.rootViewController as? UITabBarController {
+        if let tbc = window?.rootViewController as? UITabBarController {
             tbc.selectedIndex = 1
             tbc.selectedIndex = 1
             tbc.tabBar.barTintColor = .black
             tbc.tabBar.barTintColor = .black
             tbc.tabBar.backgroundColor = .black
             tbc.tabBar.backgroundColor = .black
             tbc.tabBar.tintColor = .black
             tbc.tabBar.tintColor = .black
-            
+
             for item in tbc.tabBar.items! {
             for item in tbc.tabBar.items! {
                 item.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
                 item.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
             }
             }
@@ -44,28 +42,25 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         return true
         return true
     }
     }
 
 
-    func applicationWillResignActive(_ application: UIApplication) {
+    func applicationWillResignActive(_: UIApplication) {
         // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
         // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
         // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
         // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     }
     }
 
 
-    func applicationDidEnterBackground(_ application: UIApplication) {
+    func applicationDidEnterBackground(_: UIApplication) {
         // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
         // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
         // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
         // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     }
     }
 
 
-    func applicationWillEnterForeground(_ application: UIApplication) {
+    func applicationWillEnterForeground(_: UIApplication) {
         // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
         // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     }
     }
 
 
-    func applicationDidBecomeActive(_ application: UIApplication) {
+    func applicationDidBecomeActive(_: UIApplication) {
         // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
         // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     }
     }
 
 
-    func applicationWillTerminate(_ application: UIApplication) {
+    func applicationWillTerminate(_: UIApplication) {
         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
     }
     }
-
-
 }
 }
-

+ 6 - 7
Example/BFRecordScreenKit/IntroduceController.swift

@@ -6,18 +6,17 @@
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //
 //
 
 
-import Foundation
-import BFUIKit
 import BFRecordScreenKit
 import BFRecordScreenKit
+import BFUIKit
+import Foundation
 import Photos
 import Photos
 
 
-class IntroduceController : BFBaseViewController {
-    
-    var asset:PHAsset?
+class IntroduceController: BFBaseViewController {
+    var asset: PHAsset?
 
 
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
-        
+
         let vc = BFRecordScreenController()
         let vc = BFRecordScreenController()
         if asset != nil {
         if asset != nil {
             vc.assets = [asset!]
             vc.assets = [asset!]
@@ -33,7 +32,7 @@ class IntroduceController : BFBaseViewController {
         vc.closeActionHandle = {
         vc.closeActionHandle = {
             self.backBtnClick()
             self.backBtnClick()
         }
         }
-        vc.view.frame = self.view.frame
+        vc.view.frame = view.frame
         addChildViewController(vc)
         addChildViewController(vc)
         view.addSubview(vc.view)
         view.addSubview(vc.view)
     }
     }

+ 23 - 27
Example/BFRecordScreenKit/PhotoVideoListController.swift

@@ -6,18 +6,17 @@
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //
 //
 
 
-import Foundation
-import BFUIKit
+import BFCommonKit
 import BFMaterialKit
 import BFMaterialKit
-import UIKit
 import BFRecordScreenKit
 import BFRecordScreenKit
+import BFUIKit
+import Foundation
 import Photos
 import Photos
-import BFCommonKit
+import UIKit
 
 
 class PhotoVideoListController: BFBaseViewController {
 class PhotoVideoListController: BFBaseViewController {
-    
-    var chosedAsset:PHAsset?
-    
+    var chosedAsset: PHAsset?
+
     lazy var albumController: BFPhotoAlbumController = {
     lazy var albumController: BFPhotoAlbumController = {
         let albumController = BFPhotoAlbumController()
         let albumController = BFPhotoAlbumController()
         albumController.mediaType = .video
         albumController.mediaType = .video
@@ -35,14 +34,14 @@ class PhotoVideoListController: BFBaseViewController {
         }
         }
         return albumController
         return albumController
     }()
     }()
-    
+
     lazy var changeCollecBtn: UIButton = {
     lazy var changeCollecBtn: UIButton = {
         let changeCollecBtn = UIButton(frame: CGRect(x: cDefaultMargin * 5, y: cDevice_iPhoneStatusBarHei, width: cScreenWidth - cDefaultMargin * 10, height: cDefaultMargin * 4))
         let changeCollecBtn = UIButton(frame: CGRect(x: cDefaultMargin * 5, y: cDevice_iPhoneStatusBarHei, width: cScreenWidth - cDefaultMargin * 10, height: cDefaultMargin * 4))
         changeCollecBtn.titleLabel?.lineBreakMode = .byTruncatingTail
         changeCollecBtn.titleLabel?.lineBreakMode = .byTruncatingTail
         changeCollecBtn.tintColor = BFConfig.shared.styleTitleColor
         changeCollecBtn.tintColor = BFConfig.shared.styleTitleColor
         changeCollecBtn.setTitle("我的相册", for: .normal)
         changeCollecBtn.setTitle("我的相册", for: .normal)
-        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_down", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .normal)
-        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_up", moduleName: "BFFramework",isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .selected)
+        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_down", moduleName: "BFFramework", isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .normal)
+        changeCollecBtn.setImage(UIImage.moduleImage(named: "icon_selected_up", moduleName: "BFFramework", isAssets: false)?.withRenderingMode(.alwaysTemplate), for: .selected)
         changeCollecBtn.setTitleColor(BFConfig.shared.styleTitleColor, for: .normal)
         changeCollecBtn.setTitleColor(BFConfig.shared.styleTitleColor, for: .normal)
         changeCollecBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
         changeCollecBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .medium)
         changeCollecBtn.tag = 1
         changeCollecBtn.tag = 1
@@ -50,32 +49,30 @@ class PhotoVideoListController: BFBaseViewController {
         changeCollecBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
         changeCollecBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
         return changeCollecBtn
         return changeCollecBtn
     }()
     }()
-    
+
     lazy var photoMaterialVc: BFPhotosMaterialController = {
     lazy var photoMaterialVc: BFPhotosMaterialController = {
         let vc = BFPhotosMaterialController()
         let vc = BFPhotosMaterialController()
         vc.view.backgroundColor = .black
         vc.view.backgroundColor = .black
         vc.updateFrame(newFrame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneTabBarHei))
         vc.updateFrame(newFrame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneTabBarHei))
         vc.selectedMaterialHandle = { [weak self] currentMaterialData, selectedPhotoData, _, _ in
         vc.selectedMaterialHandle = { [weak self] currentMaterialData, selectedPhotoData, _, _ in
-            if currentMaterialData?.isSelected ?? false{
+            if currentMaterialData?.isSelected ?? false {
                 self?.chosedAsset = currentMaterialData
                 self?.chosedAsset = currentMaterialData
                 if selectedPhotoData.count == 2 {
                 if selectedPhotoData.count == 2 {
                     cShowHUB(superView: nil, msg: "临时:最新选择的视频是有效的视频")
                     cShowHUB(superView: nil, msg: "临时:最新选择的视频是有效的视频")
                 }
                 }
-            }else{
+            } else {
                 self?.chosedAsset = selectedPhotoData.first
                 self?.chosedAsset = selectedPhotoData.first
             }
             }
-            
         }
         }
         return vc
         return vc
     }()
     }()
-    
+
     override func viewWillAppear(_ animated: Bool) {
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
         showNavigation()
         showNavigation()
         photoMaterialVc.hiddenNavigation()
         photoMaterialVc.hiddenNavigation()
-
     }
     }
-    
+
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
 
 
@@ -84,11 +81,11 @@ class PhotoVideoListController: BFBaseViewController {
         navHeadImageView?.addSubview(changeCollecBtn)
         navHeadImageView?.addSubview(changeCollecBtn)
         addChildViewController(photoMaterialVc)
         addChildViewController(photoMaterialVc)
         view.addSubview(photoMaterialVc.view)
         view.addSubview(photoMaterialVc.view)
-        
+
         let bottomV = UIView(frame: CGRect(x: 0, y: cScreenHeigth - cDevice_iPhoneTabBarHei, width: cScreenWidth, height: cDevice_iPhoneTabBarHei))
         let bottomV = UIView(frame: CGRect(x: 0, y: cScreenHeigth - cDevice_iPhoneTabBarHei, width: cScreenWidth, height: cDevice_iPhoneTabBarHei))
         bottomV.backgroundColor = .black
         bottomV.backgroundColor = .black
         view.addSubview(bottomV)
         view.addSubview(bottomV)
-        
+
         let nextBtn = UIButton(type: .custom)
         let nextBtn = UIButton(type: .custom)
         nextBtn.frame = CGRect(x: cScreenWidth - 80, y: 10, width: 70, height: 29)
         nextBtn.frame = CGRect(x: cScreenWidth - 80, y: 10, width: 70, height: 29)
         nextBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67")
         nextBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67")
@@ -96,9 +93,8 @@ class PhotoVideoListController: BFBaseViewController {
         nextBtn.layer.cornerRadius = 4
         nextBtn.layer.cornerRadius = 4
         nextBtn.addTarget(self, action: #selector(rightBtnClick(sender:)), for: .touchUpInside)
         nextBtn.addTarget(self, action: #selector(rightBtnClick(sender:)), for: .touchUpInside)
         bottomV.addSubview(nextBtn)
         bottomV.addSubview(nextBtn)
-        
     }
     }
-    
+
     /// 按钮点击事件
     /// 按钮点击事件
     /// - Parameter sender: <#sender description#>
     /// - Parameter sender: <#sender description#>
     /// - Returns: <#description#>
     /// - Returns: <#description#>
@@ -115,7 +111,7 @@ class PhotoVideoListController: BFBaseViewController {
             break
             break
         }
         }
     }
     }
-    
+
     /// 图库选择的回调
     /// 图库选择的回调
     /// - Parameter seletedData: <#seletedData description#>
     /// - Parameter seletedData: <#seletedData description#>
     /// - Returns: <#description#>
     /// - Returns: <#description#>
@@ -127,18 +123,18 @@ class PhotoVideoListController: BFBaseViewController {
             photoMaterialVc.assetCollection = seletedData?.assetCollection
             photoMaterialVc.assetCollection = seletedData?.assetCollection
         }
         }
     }
     }
-    
+
     override func rightBtnClick(sender _: UIButton) {
     override func rightBtnClick(sender _: UIButton) {
-        if let asset = self.chosedAsset{
+        if let asset = chosedAsset {
             let vc = IntroduceController()
             let vc = IntroduceController()
             vc.asset = asset
             vc.asset = asset
             navigationController?.pushViewController(vc, animated: true)
             navigationController?.pushViewController(vc, animated: true)
-        }else{
+        } else {
             cShowHUB(superView: nil, msg: "需要选择一个视频")
             cShowHUB(superView: nil, msg: "需要选择一个视频")
         }
         }
     }
     }
-    
+
     override open var preferredStatusBarStyle: UIStatusBarStyle {
     override open var preferredStatusBarStyle: UIStatusBarStyle {
-            return .lightContent
+        return .lightContent
     }
     }
 }
 }

+ 19 - 20
Example/BFRecordScreenKit/VideoExportController.swift

@@ -6,23 +6,22 @@
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //  Copyright © 2021 CocoaPods. All rights reserved.
 //
 //
 
 
-import Foundation
+import AVFoundation
 import BFRecordScreenKit
 import BFRecordScreenKit
 import BFUIKit
 import BFUIKit
+import Foundation
 import UIKit
 import UIKit
-import AVFoundation
 
 
-class VideoExportController: BFBaseViewController{
-    
-    var videoAsset : AVURLAsset?
-    
-    lazy var progressView : UIView = {
+class VideoExportController: BFBaseViewController {
+    var videoAsset: AVURLAsset?
+
+    lazy var progressView: UIView = {
         let v = UIView(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: 0, height: 10))
         let v = UIView(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: 0, height: 10))
         v.backgroundColor = .red
         v.backgroundColor = .red
         return v
         return v
     }()
     }()
-    
-    lazy var progressL : UILabel = {
+
+    lazy var progressL: UILabel = {
         let la = UILabel(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: cScreenWidth, height: 10))
         let la = UILabel(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: cScreenWidth, height: 10))
         la.textColor = .white
         la.textColor = .white
         la.textAlignment = .center
         la.textAlignment = .center
@@ -30,19 +29,19 @@ class VideoExportController: BFBaseViewController{
         la.font = UIFont.systemFont(ofSize: 8)
         la.font = UIFont.systemFont(ofSize: 8)
         return la
         return la
     }()
     }()
-    
-    lazy var export : BFRecordExport = {
+
+    lazy var export: BFRecordExport = {
         let export = BFRecordExport()
         let export = BFRecordExport()
-        
-        export.progress = {[weak self] progress in
-            self?.progressView.frame = CGRect(x: 0, y: self?.navHeadImageView?.bottomY ?? 0, width: (cScreenWidth) * CGFloat(progress), height: 10)
-            self?.progressL.text = String(format: "%d%%", Int(progress*100))
+
+        export.progress = { [weak self] progress in
+            self?.progressView.frame = CGRect(x: 0, y: self?.navHeadImageView?.bottomY ?? 0, width: cScreenWidth * CGFloat(progress), height: 10)
+            self?.progressL.text = String(format: "%d%%", Int(progress * 100))
         }
         }
-        export.exportCompletion = {[weak self] (error, url) in
+        export.exportCompletion = { [weak self] _, url in
             guard let strongSelf = self else {
             guard let strongSelf = self else {
                 return
                 return
             }
             }
-            
+
             if let fileUrl = url {
             if let fileUrl = url {
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
                     let item = AVPlayerItem(url: fileUrl)
                     let item = AVPlayerItem(url: fileUrl)
@@ -56,12 +55,12 @@ class VideoExportController: BFBaseViewController{
         }
         }
         return export
         return export
     }()
     }()
-    
+
     override func viewWillAppear(_ animated: Bool) {
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         super.viewWillAppear(animated)
         showNavigation()
         showNavigation()
     }
     }
-    
+
     override func backBtnClick() {
     override func backBtnClick() {
         export.cancelExport()
         export.cancelExport()
         super.backBtnClick()
         super.backBtnClick()
@@ -72,7 +71,7 @@ class VideoExportController: BFBaseViewController{
         view.backgroundColor = .black
         view.backgroundColor = .black
         navHeadImageView?.backgroundColor = .black
         navHeadImageView?.backgroundColor = .black
         leftButton(image: nil, imageName: nil, tintColor: UIColor.white)
         leftButton(image: nil, imageName: nil, tintColor: UIColor.white)
-        
+
         let backV = UIView(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: cScreenWidth, height: 10))
         let backV = UIView(frame: CGRect(x: 0, y: navHeadImageView!.bottomY, width: cScreenWidth, height: 10))
         backV.backgroundColor = .gray
         backV.backgroundColor = .gray
         view.addSubview(backV)
         view.addSubview(backV)

+ 8 - 13
Example/BFRecordScreenKit/ViewController.swift

@@ -6,26 +6,24 @@
 //  Copyright (c) 2021 harry. All rights reserved.
 //  Copyright (c) 2021 harry. All rights reserved.
 //
 //
 
 
-import UIKit
+import BFMaterialKit
 import BFMediaKit
 import BFMediaKit
 import BFRecordScreenKit
 import BFRecordScreenKit
-import BFMaterialKit
-
+import UIKit
 
 
 class ViewController: UIViewController {
 class ViewController: UIViewController {
-
-    lazy var addVideoBtn:UIButton = {
+    lazy var addVideoBtn: UIButton = {
         let btn = UIButton(type: .custom)
         let btn = UIButton(type: .custom)
 //        btn.setTitle("Add", for: .normal)
 //        btn.setTitle("Add", for: .normal)
         btn.setImage(UIImage(named: "add"), for: .normal)
         btn.setImage(UIImage(named: "add"), for: .normal)
         btn.addTarget(self, action: #selector(addVideo), for: .touchUpInside)
         btn.addTarget(self, action: #selector(addVideo), for: .touchUpInside)
         return btn
         return btn
     }()
     }()
-    
+
     override func viewDidLoad() {
     override func viewDidLoad() {
         super.viewDidLoad()
         super.viewDidLoad()
         view.backgroundColor = .black
         view.backgroundColor = .black
-        self.navigationController?.isNavigationBarHidden = true
+        navigationController?.isNavigationBarHidden = true
         view.addSubview(addVideoBtn)
         view.addSubview(addVideoBtn)
         addVideoBtn.snp.makeConstraints { make in
         addVideoBtn.snp.makeConstraints { make in
             make.width.height.equalTo(170)
             make.width.height.equalTo(170)
@@ -37,13 +35,10 @@ class ViewController: UIViewController {
         super.didReceiveMemoryWarning()
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
         // Dispose of any resources that can be recreated.
     }
     }
-    
-    @objc func addVideo(){
+
+    @objc func addVideo() {
         let vc = PhotoVideoListController()
         let vc = PhotoVideoListController()
         vc.hidesBottomBarWhenPushed = true
         vc.hidesBottomBarWhenPushed = true
-        self.navigationController?.pushViewController(vc, animated: true)
+        navigationController?.pushViewController(vc, animated: true)
     }
     }
-
 }
 }
-
-

+ 5 - 7
Example/Tests/Tests.swift

@@ -1,28 +1,26 @@
-import XCTest
 import BFRecordScreenKit
 import BFRecordScreenKit
+import XCTest
 
 
 class Tests: XCTestCase {
 class Tests: XCTestCase {
-    
     override func setUp() {
     override func setUp() {
         super.setUp()
         super.setUp()
         // Put setup code here. This method is called before the invocation of each test method in the class.
         // Put setup code here. This method is called before the invocation of each test method in the class.
     }
     }
-    
+
     override func tearDown() {
     override func tearDown() {
         // Put teardown code here. This method is called after the invocation of each test method in the class.
         // Put teardown code here. This method is called after the invocation of each test method in the class.
         super.tearDown()
         super.tearDown()
     }
     }
-    
+
     func testExample() {
     func testExample() {
         // This is an example of a functional test case.
         // This is an example of a functional test case.
         XCTAssert(true, "Pass")
         XCTAssert(true, "Pass")
     }
     }
-    
+
     func testPerformanceExample() {
     func testPerformanceExample() {
         // This is an example of a performance test case.
         // This is an example of a performance test case.
-        self.measure() {
+        measure {
             // Put the code you want to measure the time of here.
             // Put the code you want to measure the time of here.
         }
         }
     }
     }
-    
 }
 }

+ 67 - 0
rules.swiftformat

@@ -0,0 +1,67 @@
+--allman false
+--assetliterals visual-width
+--beforemarks 
+--binarygrouping 4,8
+--categorymark "MARK: %c"
+--classthreshold 0
+--closingparen balanced
+--commas always
+--conflictmarkers reject
+--decimalgrouping 3,6
+--elseposition same-line
+--enumthreshold 0
+--exponentcase lowercase
+--exponentgrouping disabled
+--extensionacl on-extension
+--extensionlength 0
+--extensionmark "MARK: - %t + %c"
+--fractiongrouping disabled
+--fragment false
+--funcattributes preserve
+--groupedextension "MARK: %c"
+--guardelse auto
+--header ignore
+--hexgrouping 4,8
+--hexliteralcase uppercase
+--ifdef indent
+--importgrouping alphabetized
+--indent 4
+--indentcase false
+--lifecycle 
+--linebreaks lf
+--markextensions always
+--marktypes always
+--maxwidth none
+--modifierorder 
+--nevertrailing 
+--nospaceoperators 
+--nowrapoperators 
+--octalgrouping 4,8
+--operatorfunc spaced
+--organizetypes class,enum,struct
+--patternlet hoist
+--ranges spaced
+--redundanttype inferred
+--self remove
+--selfrequired 
+--semicolons inline
+--shortoptionals always
+--smarttabs enabled
+--stripunusedargs always
+--structthreshold 0
+--swiftversion 4.0
+--tabwidth unspecified
+--trailingclosures 
+--trimwhitespace always
+--typeattributes preserve
+--typemark "MARK: - %t"
+--varattributes preserve
+--voidtype void
+--wraparguments preserve
+--wrapcollections preserve
+--wrapconditions preserve
+--wrapparameters preserve
+--wrapreturntype preserve
+--xcodeindentation disabled
+--yodaswap always
+--disable initCoderUnavailable,redundantType

Some files were not shown because too many files changed in this diff