Explorar el Código

多段录音的逻辑及UI渲染

harry hace 3 años
padre
commit
bd07e683e4

+ 6 - 6
BFRecordScreenKit/Classes/BFRecordItemModel.swift

@@ -9,12 +9,12 @@ import Foundation
 
 import BFFramework
 
-class BFRecordItemModel: NSObject {
+public class BFRecordItemModel: NSObject {
     var baseMaterial : AVURLAsset?
     var dealDurationRanges = [CMTimeRange]()
-    var voiceStickers = [PQVoiceModel]()
-    var videoStickers = [PQEditVisionTrackMaterialsModel]()
-    var imageStickers = [PQEditVisionTrackMaterialsModel]()
-    var titleStickers = [PQEditSubTitleModel]()
-    
+    public var voiceStickers = [PQVoiceModel]()
+    public var videoStickers = [PQEditVisionTrackMaterialsModel]()
+    public var imageStickers = [PQEditVisionTrackMaterialsModel]()
+    public var titleStickers = [PQEditSubTitleModel]()
+    public var index = 0
 }

+ 85 - 39
BFRecordScreenKit/Classes/BFRecordScreenController.swift

@@ -21,7 +21,9 @@ public class BFRecordScreenController: BFBaseViewController {
     
     // MARK: - 录制参数
     public var assets = [PHAsset]()
-    public var currAsset:PHAsset?
+    
+    var currItemModelIndex = 0
+    public var itemModels = [BFRecordItemModel]()
 //    var shouldPlayRecordIndex:Int = -1          // 当前应该播放的录音资源序号
     var currentPlayRecordIndex:Int = -1         // >= 0 :当前正在播放的录音资源序号; -3: 刚录音完,不需要播放录音; -1:初始化阶段
     var isRecording = false {                   // 是否正在录音
@@ -43,7 +45,7 @@ public class BFRecordScreenController: BFBaseViewController {
     // 视频素材
     public var avasset:AVURLAsset?
     
-    public var recordList:[PQVoiceModel] = [PQVoiceModel]()
+//    public var recordList:[PQVoiceModel] = [PQVoiceModel]()
     
     var assetPlayer:AVPlayer?       // 原视频音频播放器
     var isCompletePlay = true
@@ -69,26 +71,29 @@ public class BFRecordScreenController: BFBaseViewController {
             
         }
         manager.endRecordHandle = {[weak self] (model, error) in
-            if let model = model, FileManager.default.fileExists(atPath: model.wavFilePath ?? ""){
+            if let sself = self, let model = model, FileManager.default.fileExists(atPath: model.wavFilePath ?? ""){
                 // 加入到语音数组里
-                let ass = AVURLAsset(url: URL(fileURLWithPath: model.wavFilePath))
-                
-                model.endTime = model.startTime + CMTimeGetSeconds(ass.duration)
-                
-                // TODO: 原逻辑要删除新录音后边的数据, 新逻辑是插入覆盖
-                while let m = self?.recordList.last{
-                    if model.startTime < m.startTime {
-                        self?.recordList.removeLast()
-                    }else if m.endTime > model.startTime {
-                        m.endTime = model.startTime
-                    }else{
+                // TODO: 原逻辑要删除新录音后边的数据, 新逻辑是覆盖则删除
+                var index = sself.itemModels[sself.currItemModelIndex].voiceStickers.count - 1
+                while index >= 0{
+                    let m = sself.itemModels[sself.currItemModelIndex].voiceStickers[index]
+                    index -= 1
+                    if model.endTime > m.startTime && model.endTime <= m.endTime
+                        || model.startTime <= m.startTime && model.startTime > m.endTime{
+                        sself.itemModels[sself.currItemModelIndex].voiceStickers.remove(at: index+1)
+                        continue
+                    }
+                    if model.startTime < m.endTime {
                         break
                     }
                 }
                 BFLog(1, message: "添加录音文件:\(model.startTime) -- \(model.endTime)")
-                self?.recordList.append(model)
-                self?.drawOrUpdateRecordProgessLable()
-                self?.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
+                
+                sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
+                
+                sself.drawOrUpdateRecordProgessLable()
+                
+                sself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
             }
             
         }
@@ -369,10 +374,10 @@ public class BFRecordScreenController: BFBaseViewController {
         pause()
 
         let model = PQVoiceModel()
-        model.startTime = CMTimeGetSeconds(self.currentAssetProgress)
+        model.startTime = self.currentAssetProgress.seconds
         model.volume = 100
         recorderManager.voiceModel = model
-        recorderManager.startRecord(index: recordList.count)
+        recorderManager.startRecord(index: 1)
 //        movie?.startProcessing()
         assetPlayer?.volume = 0
         assetPlayer?.play()
@@ -382,6 +387,7 @@ public class BFRecordScreenController: BFBaseViewController {
         
         isRecording = false
         // 存储录音
+        recorderManager.voiceModel?.endTime = self.currentAssetProgress.seconds
         recorderManager.endRecord()
 
         pause()
@@ -396,8 +402,17 @@ public class BFRecordScreenController: BFBaseViewController {
     }
     @objc func withdrawAction(){
         pause()
-        recordList.removeLast()
-        drawOrUpdateRecordProgessLable()
+        if let model = itemModels[currItemModelIndex].voiceStickers.last  {
+            itemModels[currItemModelIndex].voiceStickers.removeLast()
+            drawOrUpdateRecordProgessLable()
+            if let dur = itemModels[currItemModelIndex].baseMaterial?.duration.seconds,dur > 0 {
+                changeProgress(progress: Float(model.startTime / dur))
+                isDragingProgressSlder = false
+                currentPlayRecordIndex = -1
+                hadPrepareToPlayRecord = false
+                progressThumV.progress = model.startTime
+            }
+        }
     }
     
     @objc func changeVoiceAction(){
@@ -475,7 +490,8 @@ public class BFRecordScreenController: BFBaseViewController {
         if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
             return
         }
-        let (shouldPlayRecordIndex, recordedAudio) = recordList.enumerated().first { model in
+        
+        let (shouldPlayRecordIndex, recordedAudio) = itemModels[currItemModelIndex].voiceStickers.enumerated().first { model in
             model.1.endTime > CMTimeGetSeconds(currentT)
         } ?? (-1, nil)
         
@@ -574,7 +590,14 @@ public class BFRecordScreenController: BFBaseViewController {
     
     func fetchVideo(){
         if self.assets.count > 0 {
+
+            currItemModelIndex = 0
+            
             for (index, asset) in self.assets.enumerated() {
+                let itemModel = BFRecordItemModel()
+                itemModel.index = 0
+                itemModels.append(itemModel)
+                
                 let options = PHVideoRequestOptions()
                 options.isNetworkAccessAllowed = true
                 options.deliveryMode = .automatic
@@ -611,10 +634,11 @@ public class BFRecordScreenController: BFBaseViewController {
 //                }
                 
                 PHCachingImageManager().requestAVAsset(forVideo: asset, options: options, resultHandler: {[weak self] (asset: AVAsset?, audioMix: AVAudioMix?, info) in
-                    if let urlass = asset as? AVURLAsset {
-                        self?.avasset = urlass
+                    if let urlasset = asset as? AVURLAsset {
+                        self?.avasset = urlasset
+                        itemModel.baseMaterial = urlasset
                         DispatchQueue.main.async {[weak self] in
-                            self?.progressThumV.videoAsset = urlass
+                            self?.progressThumV.videoAsset = urlasset
                             self?.progressThumV.isHidden = false
                         }
                     }
@@ -692,6 +716,24 @@ public class BFRecordScreenController: BFBaseViewController {
         
     }
     
+    func generationTimeRanges() -> [CMTimeRange]{
+        
+        var ranges = [CMTimeRange]()
+        var start : Double = 0
+        for model in itemModels[currItemModelIndex].voiceStickers {
+            if model.startTime > start{
+                let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), duration: CMTime(seconds: model.startTime - start, preferredTimescale: 100))
+                ranges.append(range)
+                
+            }
+            ranges.append(CMTimeRange(start: CMTime(seconds: model.startTime, preferredTimescale: 100), end: CMTime(seconds: model.endTime, preferredTimescale: 100)))
+            start = model.endTime
+        }
+        
+        return ranges
+    }
+    
+    
     //MARK: - 录音对应图像绘制
     
     func changeProgress(progress:Float) {
@@ -708,20 +750,24 @@ public class BFRecordScreenController: BFBaseViewController {
     }
     
     func drawOrUpdateRecordProgessLable(){
-//        DispatchQueue.main.async {[weak self] in
-//            self?.progessSildeBackV.subviews.forEach { vv in
-//                vv.removeFromSuperview()
-//            }
-//            if let totalDur = self?.currAsset?.duration, totalDur > 0, let list = self?.recordList {
-//                let width = self?.progessSildeBackV.width ?? 0
-//                let height = self?.progessSildeBackV.height ?? 0
-//                list.forEach { model in
-//                    let lineV = UIView(frame: CGRect(x: model.startTime * width / totalDur , y: 0, width: (model.endTime - model.startTime) * width / totalDur, height: height))
-//                    lineV.backgroundColor = ThemeStyleGreen()
-//                    self?.progessSildeBackV.addSubview(lineV)
-//                }
-//            }
-//        }
+        DispatchQueue.main.async {[weak self] in
+            guard let sself = self else {
+                return
+            }
+            sself.progressThumV.progessIndicateBackV.subviews.forEach { vv in
+                vv.removeFromSuperview()
+            }
+            
+            if let totalDur = sself.itemModels[sself.currItemModelIndex].baseMaterial?.duration.seconds, totalDur > 0, sself.itemModels[sself.currItemModelIndex].voiceStickers.count > 0 {
+                let width = sself.progressThumV.progessIndicateBackV.width
+                let height = sself.progressThumV.progessIndicateBackV.height
+                sself.itemModels[sself.currItemModelIndex].voiceStickers.forEach { model in
+                    let lineV = UIView(frame: CGRect(x: model.startTime * width / totalDur , y: 0, width: (model.endTime - model.startTime) * width / totalDur, height: height))
+                    lineV.backgroundColor = ThemeStyleGreen()
+                    sself.progressThumV.progessIndicateBackV.addSubview(lineV)
+                }
+            }
+        }
     }
 }
 

+ 0 - 17
BFRecordScreenKit/Classes/BFVoiceRecordManager.swift

@@ -119,25 +119,8 @@ class BFVoiceRecordManager {
                     print("Failed to remove recorder file. \(url)")
                 }
 
-//                strongSelf.recorderPart.cacheRecorderCount = strongSelf.recorderPart.cacheRecorderCount + 1
-//                strongSelf.recorderPart.audioPowers.append(strongSelf.partGap)
-//
-//                strongSelf.mergeToMP3file()
             }
 
-//            if strongSelf.recorderPart.cacheRecorderCount == 0 {
-//                strongSelf.timeLab.text = "0'"
-//                strongSelf.recorderPart.audioPowers = []
-//                strongSelf.showWater()
-//            }
-
-            // ui恢复
-
-//            if strongSelf.recorderPart.cacheRecorderCount > 0 {
-//                strongSelf.startBtn.setTitle("长按继续录制", for: .normal)
-//            } else {
-//                strongSelf.startBtn.setTitle("长按录音", for: .normal)
-//            }
         }
     }
     // 合并 成 MP3文件

+ 8 - 8
BFRecordScreenKit/Classes/View/BFVideoThumbProgressView.swift

@@ -42,6 +42,14 @@ class BFVideoThumbProgressView: UIView {
                                     lastiv.snp.makeConstraints { make in
                                         make.right.equalTo(sself.width * -0.5)
                                     }
+                                    
+                                    sself.progressView.contentView.addSubview(sself.progessIndicateBackV)
+                                    sself.progessIndicateBackV.snp.makeConstraints { make in
+                                        make.left.equalTo(sself.width * 0.5)
+                                        make.right.equalTo(sself.width * -0.5)
+                                        make.bottom.equalToSuperview()
+                                        make.height.equalTo(6)
+                                    }
                                 }
                             }
                         }
@@ -84,8 +92,6 @@ class BFVideoThumbProgressView: UIView {
     
     lazy var progessIndicateBackV : UIView = {
         let vv = UIView()
-        vv.backgroundColor = .orange // .clear
-        
         return vv
     }()
     
@@ -94,7 +100,6 @@ class BFVideoThumbProgressView: UIView {
     override init(frame: CGRect) {
         super.init(frame: frame)
         addSubview(progressView)
-        progressView.contentView.addSubview(progessIndicateBackV)
 
         let line = UIView()
         line.backgroundColor = .white
@@ -118,10 +123,6 @@ class BFVideoThumbProgressView: UIView {
         progressView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
-        progessIndicateBackV.snp.makeConstraints { make in
-            make.left.right.bottom.equalToSuperview()
-            make.height.equalTo(6)
-        }
         
     }
 }
@@ -152,7 +153,6 @@ extension BFVideoThumbProgressView : UIScrollViewDelegate {
         let dur = scrollView.contentOffset.x / (scrollView.contentSize.width - self.width)
         isDrag = false
         dragEndHandle?(Float(dur))
-
     }
     
 }