Ver Fonte

Merge branch 'master' of https://git.yishihui.com/iOS/BFRecordScreenKit
合并代码

jsonwang há 3 anos atrás
pai
commit
a2f12ad290

+ 9 - 9
BFRecordScreenKit/Classes/BFRecordExport.swift

@@ -80,11 +80,14 @@ public class BFRecordExport {
                         }
                     }
                     for srange in drangs {
-                        let range = srange.range
-                        let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds)
-                        sticker.volumeGain = 0
-                        itemModel.videoStickers.append(sticker)
-                        subDur += range.duration.seconds
+                        if let localPath = itemModel.localPath {
+                            let range = srange.range
+                            let sticker = splitBaseMaterial(timelineIn: totalDur + subDur, model_in: range.start.seconds, duration: range.duration.seconds)
+                            sticker.locationPath = localPath 
+                            sticker.volumeGain = 0
+                            itemModel.videoStickers.append(sticker)
+                            subDur += range.duration.seconds
+                        }
                     }
                     totalDur += subDur
                 }
@@ -131,9 +134,6 @@ public class BFRecordExport {
         bgMovieInfo.volumeGain = 1
         bgMovieInfo.aptDuration = bgMovieInfo.timelineOut
         bgMovieInfo.duration = bgMovieInfo.timelineOut
-        if let localPath = data?.first?.localPath {
-            bgMovieInfo.locationPath = localPath
-        }
         BFLog(1, message: "hhh- timIn:\(timelineIn), modIn:\(model_in), dur:\(duration)")
 
         return bgMovieInfo
@@ -206,7 +206,7 @@ public class BFRecordExport {
             var orgeBitRate = Int(outputSize.width * outputSize.height * 3)
 
             for stick in videoStickers {
-                if stick.type == StickerType.VIDEO.rawValue {
+                if stick.type == StickerType.VIDEO.rawValue, stick.locationPath.count > 0 {
                     let asset = AVURLAsset(url: URL(fileURLWithPath: stick.locationPath), options: avAssertOptions)
 
                     let cbr = asset.tracks(withMediaType: .video).first?.estimatedDataRate

+ 4 - 0
BFRecordScreenKit/Classes/BFRecordItemModel.swift

@@ -28,7 +28,11 @@ public class BFRecordItemModel: NSObject {
     public var videoStickers = [PQEditVisionTrackMaterialsModel]() // 合成导出时计算
     public var imageStickers = [PQEditVisionTrackMaterialsModel]() //
     public var titleStickers = [PQEditSubTitleModel]() // 字幕贴纸
+    
+    var events = [WithDrawModel]() // 行为记录,方便撤销
+
     public var coverImg: UIImage? // 封面图
+    public var thumbImgs = [UIImage]() // 缩略图集合
     public var playItem: AVPlayerItem? // 视频playerItem
     public var videoAsset: AVURLAsset? // 视频Asset
     public var mediaType: StickerType? // 素材类型

+ 0 - 0
BFVideoCompositionManager.swift → BFRecordScreenKit/Classes/BFVideoCompositionManager.swift


+ 131 - 74
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -45,6 +45,9 @@ public class BFRecordScreenController: BFBaseViewController {
             recordBtn.setTitle(isRecording ? "松手 完成" : "按住 说话", for: .normal)
             recordBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#28BE67", alpha: isRecording ? 0.6 : 1)
             playBtn.isSelected = isRecording
+            if !isRecording {
+                BFLog(1, message: "stop")
+            }
         }
     }
 
@@ -67,34 +70,38 @@ public class BFRecordScreenController: BFBaseViewController {
     var assetPlayer: AVPlayer? // 原视频音频播放器
     var isCompletePlay = true
     var hadPrepareToPlayRecord = false // 录音播放器准备
-    var recordPlayer: AVPlayer? // 录音音频播放器
-    var movie: GPUImageMovie? // 视频预览
-    var playView: GPUImageView? // 视频展示视图
+    var recordPlayer : AVPlayer? // 录音音频播放器
+    var movie : GPUImageMovie? // 视频预览
+    var playView : GPUImageView? // 视频展示视图
 
     // MARK: 行为参数
 
     var events = [WithDrawModel]() // 行为记录,方便撤销
-    var isDragingProgressSlder: Bool = false // 是否在拖动进度条
+    var isDragingProgressSlder : Bool = false // 是否在拖动进度条
     var isStopAtRecordRange = -1
 
     // 保存识别出来的字幕信息,用于回放,和合成使用
 //    var saveSubTitles:[PQEditSubTitleModel] = Array.init()
+    
+    //MARK: - 录音相关
+
     // 定义音频的编码参数
-    let recordSettings: [String: Any] = [AVSampleRateKey: 44100.0, // 声音采样率
+    let recordSettings : [String: Any] = [AVSampleRateKey: 44100.0, // 声音采样率
                                          AVFormatIDKey: kAudioFormatLinearPCM, // 编码格式
                                          AVNumberOfChannelsKey: 1, // 采集音轨
                                          AVEncoderBitDepthHintKey: 16, // 位深
                                          AVEncoderAudioQualityKey: AVAudioQuality.medium.rawValue] // 音频质量
 
-    // 录音相关
-    lazy var recorderManager: BFVoiceRecordManager = {
+    var haveSpeakVolume : Float = 0
+    var noSpeakVolume : Float = 1
+    
+    lazy var recorderManager : BFVoiceRecordManager = {
         let manager = BFVoiceRecordManager()
         manager.cancelRecordHandle = { _ in
         }
         manager.endRecordHandle = { [weak self] model, _ in
             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))
@@ -114,10 +121,7 @@ public class BFRecordScreenController: BFBaseViewController {
                     return CMTimeRangeGetIntersection(originRange, otherRange: newRange).duration.seconds > 0
                 }
                 BFLog(1, message: "添加录音文件:\(model.startTime) -- \(model.endTime)")
-                sself.withDrawBtn.setTitle("撤销录制", for: .normal)
-                DispatchQueue.main.async {[weak self] in
-                    self?.changeWithDrawBtnLayout()
-                }
+                
                 var event = sself.events.last
                 if event != nil {
                     event!.deletedVoices = deletedVoices
@@ -135,7 +139,13 @@ public class BFRecordScreenController: BFBaseViewController {
                     model.endTime = sself.currentAssetProgress.seconds
                     self?.isEndPlay = true
                 }
-                sself.drawOrUpdateRecordProgessLable()
+                DispatchQueue.main.async {[weak self] in
+                    // 录音完,重绘撤销按钮,更新录音按钮,
+                    self?.changeWithDrawBtnLayout(true)
+                    self?.drawOrUpdateRecordProgessLable()
+                    self?.deleteRecordBtn.isHidden = true
+                    self?.recordBtn.isHidden = false
+                }
 
                 sself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
             }
@@ -151,10 +161,10 @@ public class BFRecordScreenController: BFBaseViewController {
 
     var indirectionView: BFIndirectionProgressView?
     
-    lazy var progreddL: UILabel = {
+    lazy var progreddL : UILabel = {
         let l = UILabel()
         l.textAlignment = .center
-        l.font = UIFont.systemFont(ofSize: 10)
+        l.font = UIFont.systemFont(ofSize: 13)
         l.textColor = .white
         l.shadowColor = .black
         l.shadowOffset = CGSize(width: 1, height: 1)
@@ -162,7 +172,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return l
     }()
 
-    lazy var playBtn: UIButton = {
+    lazy var playBtn : UIButton = {
         let btn = UIButton(frame: view.bounds)
         btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
         let vv = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
@@ -171,7 +181,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var bottomeView: UIImageView = {
+    lazy var bottomeView : UIImageView = {
         let iv = UIImageView(image: imageInRecordScreenKit(by: "bottom_shadow"))
         iv.contentMode = .scaleAspectFill
         iv.isUserInteractionEnabled = true
@@ -185,10 +195,11 @@ public class BFRecordScreenController: BFBaseViewController {
         return iv
     }()
 
-    lazy var recordBtn: UIButton = {
+    lazy var recordBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.backgroundColor = ThemeStyleColor
         btn.setTitle("按住 说话", for: .normal)
+        btn.addCorner(corner:6)
         btn.adjustsImageWhenHighlighted = false
         btn.addTarget(self, action: #selector(startRecord), for: .touchDown)
         btn.addTarget(self, action: #selector(endRecord), for: .touchUpInside)
@@ -196,22 +207,22 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var deleteRecordBtn: UIButton = {
+    lazy var deleteRecordBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.backgroundColor = .red
-        btn.alpha = 0.5
         btn.setTitle("删除录制", for: .normal)
         btn.adjustsImageWhenHighlighted = false
+        btn.addCorner(corner:6)
         btn.addTarget(self, action: #selector(deleteRecorded), for: .touchUpInside)
         btn.isHidden = true
         return btn
     }()
 
-    lazy var withDrawBtn: UIButton = {
+    lazy var withDrawBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "withdraw_n"), for: .normal)
         btn.setImage(imageInRecordScreenKit(by: "withdraw_h"), for: .highlighted)
-        btn.setTitle("撤销", for: .normal)
+        btn.setTitle("回退", for: .normal)
         btn.setTitleColor(.white, for: .normal)
         btn.setTitleColor(.gray, for: .highlighted)
         btn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
@@ -220,7 +231,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var changeVoiceBtn: UIButton = {
+    lazy var changeVoiceBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "changeVoice_n"), for: .normal)
         btn.setImage(imageInRecordScreenKit(by: "changeVoice_h"), for: .highlighted)
@@ -233,7 +244,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var toolV: BFIntroduceToolView = {
+    lazy var toolV : BFIntroduceToolView = {
         let toolV = BFIntroduceToolView()
         toolV.centerY = view.centerY
 
@@ -250,14 +261,14 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 头像  add by ak
-    lazy var avatarView: BFRecordAvatarView = {
+    lazy var avatarView : BFRecordAvatarView = {
         let avatarView = BFRecordAvatarView(frame: CGRect(x: 10, y: 10, width: 120, height: 120))
         avatarView.isHidden = true
         return avatarView
     }()
 
     // 打开摄像头
-    lazy var openCameraBtn: UIButton = {
+    lazy var openCameraBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "openCamera"), for: .normal)
         btn.addTarget(self, action: #selector(openCamera), for: .touchUpInside)
@@ -265,7 +276,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 画笔
-    lazy var drawPinBtn: UIButton = {
+    lazy var drawPinBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "drawPin"), for: .normal)
         btn.addTarget(self, action: #selector(drawPin), for: .touchUpInside)
@@ -273,7 +284,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 字幕设置
-    lazy var subtitleBtn: UIButton = {
+    lazy var subtitleBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "subtitleBtn"), for: .normal)
         btn.addTarget(self, action: #selector(subTitleClick), for: .touchUpInside)
@@ -281,7 +292,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 声音设置
-    lazy var soundSettingBtn: UIButton = {
+    lazy var soundSettingBtn : UIButton = {
         let btn = UIButton(type: .custom)
         btn.setImage(imageInRecordScreenKit(by: "soundBtn"), for: .normal)
         btn.addTarget(self, action: #selector(soundSetting), for: .touchUpInside)
@@ -289,14 +300,14 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 字幕设置面板
-    lazy var subtitleSettingView: BFSubtitleSettingView = {
+    lazy var subtitleSettingView : BFSubtitleSettingView = {
         let subtitleSetting = BFSubtitleSettingView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
         subtitleSetting.isHidden = true
         return subtitleSetting
     }()
 
     // 编辑字幕
-    lazy var subtitleEditView: BFSubtitleEditView = {
+    lazy var subtitleEditView : BFSubtitleEditView = {
         let subtitleEditView = BFSubtitleEditView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
         subtitleEditView.isHidden = true
 
@@ -304,7 +315,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 显示字幕
-    lazy var subtitleLabel: PQSubTitleLabel = {
+    lazy var subtitleLabel : PQSubTitleLabel = {
         let subtitleLabel = PQSubTitleLabel()
         subtitleLabel.textAlignment = .center
         subtitleLabel.numberOfLines = 0
@@ -316,16 +327,24 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 音量设置
-    lazy var audioSettingView: BFAudioSettingView = {
+    lazy var audioSettingView : BFAudioSettingView = {
         let audioSettingView = BFAudioSettingView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
         audioSettingView.isHidden = true
+        audioSettingView.haveSpeakSlider.valueIsInt = true
+        audioSettingView.noSpeakSlider.valueIsInt = true
+        audioSettingView.callBack = {[weak self] haveSpeak, noHaveSpeak in
+            BFLog(1, message: "haveSpeak is:\(haveSpeak),noHaveSpeak is:\(noHaveSpeak)")
+            self?.haveSpeakVolume = haveSpeak / 100.0
+            self?.noSpeakVolume = noHaveSpeak / 100.0
+        }
+
         return audioSettingView
     }()
 
     // 录音识别文字
-    var speechTranscriberUtil: PQSpeechTranscriberUtil?
+    var speechTranscriberUtil : PQSpeechTranscriberUtil?
 
-    lazy var progressThumV: BFVideoThumbProgressView = {
+    lazy var progressThumV : BFVideoThumbProgressView = {
         let vv = BFVideoThumbProgressView(frame: CGRect(x: 0, y: 54, width: cScreenWidth, height: 50))
         vv.dragStartHandle = { [weak self] in
             self?.isDragingProgressSlder = true
@@ -339,25 +358,30 @@ public class BFRecordScreenController: BFBaseViewController {
                 if isStart {
                     sself.events.append(WithDrawModel(type: 0, timestamp: sself.currentAssetProgress.seconds))
                 }
+                if !sself.isDragingProgressSlder {
+                    BFLog(1, message: "isDragingProgressSlder 进行中")
+
+                }
                 sself.isDragingProgressSlder = true
 
-//                BFLog(1, message: "drag 进行中")
+                BFLog(1, message: "isDragingProgressSlder 进行中")
 
                 sself.changeProgress(progress: process)
             }
         }
         vv.dragEndHandle = { [weak self] process in
-
-            guard let sself = self else {
-                return
+            DispatchQueue.main.async { [weak self] in
+                guard let sself = self else {
+                    return
+                }
+                sself.thumbViewEnded(progress: process)
             }
-            sself.thumbViewEnded(progress: process)
         }
         vv.isHidden = true
         return vv
     }()
 
-    lazy var collectionView: UICollectionView = {
+    lazy var collectionView : UICollectionView = {
         let flowLayout = UICollectionViewFlowLayout()
         flowLayout.minimumLineSpacing = 0
         flowLayout.minimumInteritemSpacing = 0
@@ -448,10 +472,6 @@ public class BFRecordScreenController: BFBaseViewController {
             BFLog(message: "新录制完成::::\(materialsModel?.locationPath ?? "")")
         }
 
-        audioSettingView.callBack = { haveSpeak, noHaveSpeak in
-
-            BFLog(message: "haveSpeak is\(haveSpeak),noHaveSpeak is\(noHaveSpeak)")
-        }
 
         // 字幕设置回调
         // 设置默认值
@@ -714,7 +734,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }
 
     @objc func deleteRecorded() {
-        if isStopAtRecordRange != -1, isStopAtRecordRange < itemModels[currItemModelIndex].voiceStickers.count {
+        if !isDragingProgressSlder, isStopAtRecordRange != -1, isStopAtRecordRange < itemModels[currItemModelIndex].voiceStickers.count {
             let model = itemModels[currItemModelIndex].voiceStickers[isStopAtRecordRange]
             itemModels[currItemModelIndex].voiceStickers.remove(at: isStopAtRecordRange)
             events.append(WithDrawModel(type: 3, timestamp: currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)]))
@@ -727,11 +747,12 @@ public class BFRecordScreenController: BFBaseViewController {
     }
 
     @objc func startRecord() {
-        BFLog(1, message: "start \(UIControl.Event.touchDown)")
+//        BFLog(1, message: "start \(UIControl.Event.touchDown)")
 
         // 停止进度条滚动
-        let point = progressThumV.progressView.contentOffset
-        progressThumV.progressView.setContentOffset(point, animated: false)
+        if isDragingProgressSlder {
+             return
+        }
 
         pause()
         isRecording = true
@@ -743,7 +764,7 @@ public class BFRecordScreenController: BFBaseViewController {
         recorderManager.startRecord(index: 1)
 
         movie?.startProcessing()
-        assetPlayer?.volume = 0
+        assetPlayer?.volume = self.haveSpeakVolume
         assetPlayer?.play()
         isRecording = true
 
@@ -877,11 +898,9 @@ public class BFRecordScreenController: BFBaseViewController {
             }
 
             if let event = events.last, event.type == 2 {
-                withDrawBtn.setTitle("撤销录制", for: .normal)
-                changeWithDrawBtnLayout()
+                changeWithDrawBtnLayout(true)
             } else {
-                withDrawBtn.setTitle("撤销", for: .normal)
-                changeWithDrawBtnLayout()
+                changeWithDrawBtnLayout(false)
             }
             searchStopAtRecordRange()
         }
@@ -898,7 +917,7 @@ public class BFRecordScreenController: BFBaseViewController {
             searchStopAtRecordRange()
         } else {
             events.append(WithDrawModel(type: 1, timestamp: currentAssetProgress.seconds))
-            withDrawBtn.setTitle("撤销", for: .normal)
+            changeWithDrawBtnLayout(false)
             play()
         }
     }
@@ -924,9 +943,9 @@ public class BFRecordScreenController: BFBaseViewController {
         isDragingProgressSlder = false
         currentPlayRecordIndex = -1
         hadPrepareToPlayRecord = false
-        BFLog(1, message: isDragingProgressSlder ? "drag false" : "drag  tr")
+        BFLog(1, message: "isDragingProgressSlder : \(isDragingProgressSlder)")
         searchStopAtRecordRange()
-        withDrawBtn.setTitle("撤销", for: .normal)
+        changeWithDrawBtnLayout(false)
     }
 
     func searchStopAtRecordRange() {
@@ -939,11 +958,29 @@ public class BFRecordScreenController: BFBaseViewController {
 
         if elems.count > 0 {
             //  TODO: 停在了录音区间,显示删除按钮
-            deleteRecordBtn.isHidden = false
-            recordBtn.isHidden = true
-
-            isStopAtRecordRange = elems.first!.0
-            BFLog(1, message: "停在了录音区间里 \(isStopAtRecordRange)")
+            if fabs(elems[0].1.endTime - self.currentAssetProgress.seconds) < 0.5 {
+                BFLog(1, message: "吸附在录音结尾")
+                changeWithDrawBtnLayout(false)
+                changeProgress(progress: Float(elems[0].1.endTime / itemModels[currItemModelIndex].materialDuraion))
+                progressThumV.progress = elems[0].1.endTime
+                
+                deleteRecordBtn.isHidden = true
+                recordBtn.isHidden = false
+                isStopAtRecordRange = -1
+                BFLog(1, message: "停在了录音区间外 \(isStopAtRecordRange)")
+            }else {
+                if fabs(elems[0].1.startTime - self.currentAssetProgress.seconds) < 0.5 {
+                    BFLog(1, message: "吸附在录音开始")
+                    changeWithDrawBtnLayout(true)
+                    changeProgress(progress: Float(elems[0].1.startTime / itemModels[currItemModelIndex].materialDuraion))
+                    progressThumV.progress = elems[0].1.startTime
+                }
+                deleteRecordBtn.isHidden = false
+                recordBtn.isHidden = true
+                isStopAtRecordRange = elems.first!.0
+                
+                BFLog(1, message: "停在了录音区间里 \(isStopAtRecordRange)")
+            }
         } else {
             deleteRecordBtn.isHidden = true
             recordBtn.isHidden = false
@@ -1026,6 +1063,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 if let playItem = player.currentItem {
                     NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: playItem)
                     recordPlayer?.replaceCurrentItem(with: newItem)
+                    assetPlayer?.volume = self.noSpeakVolume
                 }
             } else {
                 recordPlayer = AVPlayer(playerItem: newItem)
@@ -1069,7 +1107,7 @@ public class BFRecordScreenController: BFBaseViewController {
                         self?.recordPlayer?.seek(to: CMTime(value: CMTimeValue(second * 1_000_000), timescale: 1_000_000), toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000), completionHandler: { [weak self] finished in
                             if finished, self?.isNormalPlaying ?? false {
                                 self?.recordPlayer?.play()
-
+                                self?.assetPlayer?.volume = self?.haveSpeakVolume ?? 0
                                 BFLog(1, message: "录音开始播放 playing, \(second), \(CMTimeGetSeconds(self?.recordPlayer?.currentItem?.duration ?? .zero)), \(self?.recordPlayer?.currentItem?.currentTime().seconds ?? 0)")
                             }
                         })
@@ -1118,7 +1156,7 @@ public class BFRecordScreenController: BFBaseViewController {
             currentAssetProgress = CMTime.zero
         }
         if itemModels[currItemModelIndex].mediaType == .VIDEO {
-            // assetPlayer?.volume = 0.2
+            assetPlayer?.volume = 1
             movie?.startProcessing()
             assetPlayer?.play()
         } else {
@@ -1229,8 +1267,10 @@ public class BFRecordScreenController: BFBaseViewController {
             //            self?.currentPlayRecordIndex = -1
             if self?.isRecording ?? false {
                 self?.endRecord()
+                cShowHUB(superView: nil, msg: "此视频已录制到头了哦!")
             }
-            self?.recordBtn.isHidden = true
+            (self?.collectionView.cellForItem(at: IndexPath(item: self!.currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = false
+
         }
     }
 
@@ -1244,7 +1284,8 @@ public class BFRecordScreenController: BFBaseViewController {
             if CMTimeGetSeconds(item?.duration ?? CMTime.zero) > 0 {
                 DispatchQueue.main.async { [weak self] in
                     self?.progreddL.text = String(format: "%@", CMTimeGetSeconds(time).formatDurationToHMS())
-                    let su = !(self?.isDragingProgressSlder ?? false) || (self?.isRecording ?? false && self?.isNormalPlaying ?? false)
+                    let su = !(self?.isDragingProgressSlder ?? false) || (self?.isRecording ?? false ) || (self?.isNormalPlaying ?? false)
+//                    BFLog(1, message: "进度监控:isDragingProgressSlder-\(self?.isDragingProgressSlder ?? false), isRecording - \(self?.isRecording ?? false), isNormalPlaying - \(self?.isNormalPlaying ?? false), su - \(su)")
                     if su {
                         self?.progressThumV.progress = time.seconds
                     }
@@ -1269,14 +1310,21 @@ public class BFRecordScreenController: BFBaseViewController {
     // MARK: - 录音对应图像绘制
     
     // 撤销按钮修改title,重绘
-    func changeWithDrawBtnLayout() {
+    func changeWithDrawBtnLayout(_ recorded:Bool) {
+        if recorded {
+            withDrawBtn.setTitle("撤销录制", for: .normal)
+        }else {
+            withDrawBtn.setTitle("回退", for: .normal)
+        }
         withDrawBtn.imageEdgeInsets = UIEdgeInsets(top: -withDrawBtn.imageView!.height, left: 0, bottom: 0, right: -withDrawBtn.titleLabel!.width)
         withDrawBtn.titleEdgeInsets = UIEdgeInsets(top: withDrawBtn.titleLabel!.height + 2, left: -withDrawBtn.imageView!.width, bottom: 0, right: 0)
         
         withDrawBtn.setNeedsLayout()
         withDrawBtn.layoutIfNeeded()
+        
     }
 
+    // 通过缩略图进度条控制播放进度
     func changeProgress(progress: Float) {
         if itemModels[currItemModelIndex].mediaType == .VIDEO {
             if let duration = assetPlayer?.currentItem?.duration {
@@ -1284,7 +1332,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 DispatchQueue.main.async { [weak self] in
                     self!.progreddL.text = String(format: "%@", CMTimeGetSeconds(self!.currentAssetProgress).formatDurationToHMS())
                 }
-                assetPlayer!.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1000), toleranceAfter: CMTime(value: 1, timescale: 1000)) { _ in
+                assetPlayer!.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000)) { _ in
                 }
             }
         } else {
@@ -1423,22 +1471,31 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             // 暂停状态
             let lastCell: BFImageCoverViewCell? = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell
             lastCell?.playBtn.isSelected = false
-            // 更新当前page
-            currItemModelIndex = page
-            let recordItem = itemModels[currItemModelIndex]
+            
+            let recordItem = itemModels[page]
             // 重绘录音区域
             drawOrUpdateRecordProgessLable()
             // 更新缩略图
             progressThumV.recordItem = recordItem
             progressThumV.isHidden = false
             if recordItem.mediaType == .VIDEO {
-                let currCell: BFImageCoverViewCell? = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell
-                setAudioPlay(item: recordItem.playItem)
+                let currCell: BFImageCoverViewCell? = collectionView.cellForItem(at: IndexPath(item: page, section: 0)) as? BFImageCoverViewCell
                 setVideoPlay(item: recordItem.playItem, imageView: currCell?.playView)
+                setAudioPlay(item: recordItem.playItem)
+                assetPlayer?.seek(to: .zero, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000))
             }
             if changeItemHandle != nil {
-                changeItemHandle!(currItemModelIndex)
+                changeItemHandle!(page)
+            }
+            // 重设撤销栈
+            itemModels[currItemModelIndex].events = events
+            events = itemModels[page].events
+            if let cell = collectionView.visibleCells.first as? BFImageCoverViewCell{
+                playBtn = cell.playBtn
             }
+            
+            // 更新当前page
+            currItemModelIndex = page
         }
     }
 

+ 13 - 6
BFRecordScreenKit/Classes/RecordScreen/View/BFVideoThumbProgressView.swift

@@ -94,10 +94,17 @@ class BFVideoThumbProgressView: UIView {
         guard let videoAsset = recordItem?.videoAsset else {
             return
         }
+        self.addThumbImages(images: recordItem!.thumbImgs)
+        if recordItem!.thumbImgs.count > 0{
+            return
+        }
+        
         let dur = videoAsset.duration.seconds
         if dur > 0 {
             let fps = Double(fetchThumbStrategy.frameNumberOfVideo(assetDuration: dur)) / dur
             splitVideoFileUrlFps(urlAsset: videoAsset, fps: fps) { [weak self] images in
+                self?.recordItem!.thumbImgs.removeAll()
+                self?.recordItem!.thumbImgs.append(contentsOf: images)
                 self?.addThumbImages(images: images)
             }
         }
@@ -114,12 +121,12 @@ class BFVideoThumbProgressView: UIView {
     /// 添加缩略图
     /// - Parameter images: <#images description#>
     func addThumbImages(images: [UIImage]) {
-        if images.count > 0 {
-            thumbImgs = images
-            DispatchQueue.main.async { [weak self] in
-                self?.progressView.contentView.subviews.forEach { subview in
-                    subview.removeFromSuperview()
-                }
+        DispatchQueue.main.async { [weak self] in
+            self?.progressView.contentView.subviews.forEach { subview in
+                subview.removeFromSuperview()
+            }
+            if images.count > 0 {
+                self?.thumbImgs = images
                 if let sself = self {
                     var lastiv = UIImageView()
                     for (i, img) in images.enumerated() {