瀏覽代碼

撤销逻辑补充

harry 3 年之前
父節點
當前提交
a35ff5b1b6
共有 1 個文件被更改,包括 113 次插入23 次删除
  1. 113 23
      BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

+ 113 - 23
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -15,8 +15,9 @@ import Photos
 import UIKit
 
 struct WithDrawModel {
-    var type: Int // 0:拖动; 1:预览播放暂停 2: 录音结束
+    var type: Int // 0:拖动; 1:预览播放暂停 2: 录音结束  3: 删除录音
     var timestamp: Double
+    var deletedVoices : [(PQVoiceModel, Int)]?
 }
 
 public class BFRecordScreenController: BFBaseViewController {
@@ -38,6 +39,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
             recordBtn.setTitle(isRecording ? "松手 完成" : "按住 说话", for: .normal)
             recordBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67", alpha: isRecording ? 0.6 : 1)
+            playBtn.isSelected = isRecording
         }
     }
 
@@ -88,16 +90,33 @@ public class BFRecordScreenController: BFBaseViewController {
             if let sself = self, let model = model, FileManager.default.fileExists(atPath: model.wavFilePath ?? "") {
                 // 加入到语音数组里
                 // TODO: 原逻辑要删除新录音后边的数据, 新逻辑是覆盖则删除
+                model.endTime = sself.currentAssetProgress.seconds
+
+                let newRange = CMTimeRange(start: CMTime(seconds: model.startTime, preferredTimescale: 1000), end: CMTime(seconds: model.endTime, preferredTimescale: 1000))
+
+                var deletedVoices = [(PQVoiceModel, Int)]()
+                
                 for (i, m) in sself.itemModels[sself.currItemModelIndex].voiceStickers.enumerated() {
-                    if model.endTime > m.startTime && model.endTime <= m.endTime
-                        || model.startTime <= m.startTime && model.startTime > m.endTime
-                    {
-                        sself.itemModels[sself.currItemModelIndex].voiceStickers.remove(at: i)
+                    let originRange = CMTimeRange(start: CMTime(seconds: m.startTime, preferredTimescale: 1000), end: CMTime(seconds: m.endTime, preferredTimescale: 1000))
+                    
+                    if CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0{
+                        deletedVoices.append((m, i))
                         continue
                     }
                 }
+                sself.itemModels[sself.currItemModelIndex].voiceStickers.removeAll { m in
+                    let originRange = CMTimeRange(start: CMTime(seconds: m.startTime, preferredTimescale: 1000), end: CMTime(seconds: m.endTime, preferredTimescale: 1000))
+                    return CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0
+                }
                 BFLog(1, message: "添加录音文件:\(model.startTime) -- \(model.endTime)")
-
+                sself.withDrawBtn.setTitle("撤销录制", for: .normal)
+                var event = sself.events.last
+                if event != nil {
+                    event!.deletedVoices = deletedVoices
+                    sself.events.removeLast()
+                    sself.events.append(event!)
+                }
+                
                 sself.itemModels[sself.currItemModelIndex].voiceStickers.append(model)
 
                 sself.drawOrUpdateRecordProgessLable()
@@ -158,6 +177,16 @@ public class BFRecordScreenController: BFBaseViewController {
 
         return btn
     }()
+    lazy var deleteRecordBtn: UIButton = {
+        let btn = UIButton(type: .custom)
+        btn.backgroundColor = .red
+        btn.alpha = 0.5
+        btn.setTitle("删除录制", for: .normal)
+        btn.adjustsImageWhenHighlighted = false
+        btn.addTarget(self, action: #selector(deleteRecorded), for: .touchUpInside)
+        btn.isHidden = true
+        return btn
+    }()
 
     lazy var withDrawBtn: UIButton = {
         let btn = UIButton(type: .custom)
@@ -372,6 +401,7 @@ public class BFRecordScreenController: BFBaseViewController {
         bottomeView.addSubview(progreddL)
         //        view.addSubview(toolV)
         bottomeView.addSubview(recordBtn)
+        bottomeView.addSubview(deleteRecordBtn)
         bottomeView.addSubview(withDrawBtn)
         //        bottomeView.addSubview(changeVoiceBtn)
         bottomeView.addSubview(progressThumV)
@@ -482,6 +512,12 @@ public class BFRecordScreenController: BFBaseViewController {
             make.height.equalTo(42)
             make.top.equalTo(withDrawBtn).offset(6)
         }
+        deleteRecordBtn.snp.makeConstraints { make in
+            make.left.equalTo(withDrawBtn.snp.right)
+            make.right.equalTo(-65)
+            make.height.equalTo(42)
+            make.top.equalTo(withDrawBtn).offset(6)
+        }
 
         //        openCameraBtn.snp.makeConstraints { make in
         //            make.right.equalToSuperview().offset(-12)
@@ -592,16 +628,34 @@ public class BFRecordScreenController: BFBaseViewController {
         audioSettingView.isHidden = false
  
     }
+    
+    
+    @objc func deleteRecorded(){
+        if isStopAtRecordRange != -1, isStopAtRecordRange < itemModels[currItemModelIndex].voiceStickers.count {
+            let model = itemModels[currItemModelIndex].voiceStickers[isStopAtRecordRange]
+            itemModels[currItemModelIndex].voiceStickers.remove(at: isStopAtRecordRange)
+            drawOrUpdateRecordProgessLable()
+            searchStopAtRecordRange()
+            events.append(WithDrawModel(type: 3, timestamp: self.currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)]))
+        }
+    }
 
     @objc func startRecord() {
         BFLog(1, message: "start \(UIControl.Event.touchDown)")
 
+        // 停止进度条滚动
         let point = progressThumV.progressView.contentOffset
         progressThumV.progressView.setContentOffset(point, animated: false)
 
-        isRecording = true
         pause()
+        isRecording = true
 
+        let model = PQVoiceModel()
+        model.startTime = currentAssetProgress.seconds
+        model.volume = 100
+        recorderManager.voiceModel = model
+        recorderManager.startRecord(index: 1)
+        
         movie?.startProcessing()
         assetPlayer?.volume = 0
         assetPlayer?.play()
@@ -611,11 +665,7 @@ public class BFRecordScreenController: BFBaseViewController {
             avatarView.beginRecord()
         }
 
-        let model = PQVoiceModel()
-        model.startTime = currentAssetProgress.seconds
-        model.volume = 100
-        recorderManager.voiceModel = model
-        recorderManager.startRecord(index: 1)
+        
 
         // 添加撤销记录点
         events.append(WithDrawModel(type: 2, timestamp: model.startTime))
@@ -639,14 +689,13 @@ public class BFRecordScreenController: BFBaseViewController {
         DispatchQueue.global().async {
             self.speechTranscriberUtil?.endTranscriber()
         }
-        playBtn.isSelected = true
+//        playBtn.isSelected = true
         // 存储录音
         isRecording = false
+        pause()
 
-        recorderManager.voiceModel?.endTime = currentAssetProgress.seconds
         recorderManager.endRecord()
 
-        pause()
         if !avatarView.isHidden {
             avatarView.endRecord()
         }
@@ -670,10 +719,35 @@ public class BFRecordScreenController: BFBaseViewController {
                 }) {
                     let model = itemModels[currItemModelIndex].voiceStickers[modelIndex]
                     itemModels[currItemModelIndex].voiceStickers.remove(at: modelIndex)
+                    
+                    var tuples = action.deletedVoices
+                    if tuples != nil, tuples!.count > 0 {
+                        tuples!.sort { tuple1, tuple2 in
+                            tuple1.1 < tuple2.1
+                        }
+                        tuples?.forEach({ tuple in
+                            itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
+                        })
+                    }
+                    
                     drawOrUpdateRecordProgessLable()
                     jumpTime = model.startTime
                 }
-            } else {}
+            } else if action.type == 3 {
+                // 删除录音
+                var tuples = action.deletedVoices
+                if tuples != nil, tuples!.count > 0 {
+                    tuples!.sort { tuple1, tuple2 in
+                        tuple1.1 < tuple2.1
+                    }
+                    tuples?.forEach({ tuple in
+                        itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
+                    })
+                }
+                drawOrUpdateRecordProgessLable()
+            } else {
+                
+            }
             events.removeLast()
             let dur = itemModels[currItemModelIndex].materialDuraion
             if dur > 0 {
@@ -683,6 +757,13 @@ public class BFRecordScreenController: BFBaseViewController {
                 hadPrepareToPlayRecord = false
                 progressThumV.progress = jumpTime
             }
+            
+            if let event = events.last,  event.type == 2{
+                withDrawBtn.setTitle("撤销录制", for: .normal)
+            }else{
+                withDrawBtn.setTitle("撤销", for: .normal)
+            }
+            searchStopAtRecordRange()
         }
     }
 
@@ -697,6 +778,7 @@ public class BFRecordScreenController: BFBaseViewController {
             searchStopAtRecordRange()
         } else {
             events.append(WithDrawModel(type: 1, timestamp: currentAssetProgress.seconds))
+            withDrawBtn.setTitle("撤销", for: .normal)
             play()
         }
     }
@@ -724,10 +806,12 @@ public class BFRecordScreenController: BFBaseViewController {
         hadPrepareToPlayRecord = false
         BFLog(1, message: isDragingProgressSlder ? "drag false" : "drag  tr")
         searchStopAtRecordRange()
+        withDrawBtn.setTitle("撤销", for: .normal)
+
     }
 
     func searchStopAtRecordRange() {
-        // TODO: 判断是否停止录音区间,是则删除相关录音,画笔,头像,字幕
+        // TODO: 滑动,播放暂停,撤销时,判断是否停止录音区间,是则删除相关录音,画笔,头像,字幕
         let elems = itemModels[currItemModelIndex].voiceStickers.enumerated().filter { elem in
             elem.1.startTime <= self.currentAssetProgress.seconds && elem.1.endTime > self.currentAssetProgress.seconds
         }
@@ -735,11 +819,17 @@ public class BFRecordScreenController: BFBaseViewController {
 
         if elems.count > 0 {
             //  TODO: 停在了录音区间,显示删除按钮
+            deleteRecordBtn.isHidden = false
+            recordBtn.isHidden = true
+            
             isStopAtRecordRange = elems.first!.0
-            BFLog(1, message: "停在了录音区间 里")
+            BFLog(1, message: "停在了录音区间里 \(isStopAtRecordRange)")
         } else {
+            deleteRecordBtn.isHidden = true
+            recordBtn.isHidden = false
+            
             isStopAtRecordRange = -1
-            BFLog(1, message: "停在了录音区间 外")
+            BFLog(1, message: "停在了录音区间外 \(isStopAtRecordRange)")
         }
     }
 
@@ -971,8 +1061,8 @@ public class BFRecordScreenController: BFBaseViewController {
             avplayerTimeObserver = assetPlayer?.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 100), queue: DispatchQueue.global()) { [weak self] time in
                 //    进度监控
 
-                self?.currentAssetProgress = time
-                BFLog(1, message: "curr:\(CMTimeGetSeconds(time))")
+                self?.currentAssetProgress = CMTime(seconds: time.seconds, preferredTimescale: 1000)
+                BFLog(1, message: "curr:\(CMTimeGetSeconds(self?.currentAssetProgress ?? .zero))")
                 if CMTimeGetSeconds(item.duration) > 0 {
                     DispatchQueue.main.async { [weak self] in
                         self?.progreddL.text = String(format: "%@", CMTimeGetSeconds(time).formatDurationToHMS())
@@ -1022,12 +1112,12 @@ public class BFRecordScreenController: BFBaseViewController {
 
     func changeProgress(progress: Float) {
         if let duration = assetPlayer?.currentItem?.duration {
-            currentAssetProgress = CMTime(value: CMTimeValue(progress * Float(CMTimeGetSeconds(duration)) * 100), timescale: 100)
+            currentAssetProgress = CMTime(value: CMTimeValue(progress * Float(CMTimeGetSeconds(duration)) * 1000), timescale: 1000)
             DispatchQueue.main.async { [weak self] in
                 self!.progreddL.text = String(format: "%@", CMTimeGetSeconds(self!.currentAssetProgress).formatDurationToHMS())
             }
 
-            assetPlayer!.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000)) { _ in
+            assetPlayer!.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000)) { _ in
             }
         }
     }