Prechádzať zdrojové kódy

Merge branch 'master' of https://git.yishihui.com/iOS/BFRecordScreenKit

# Conflicts:
#	BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift
合并代码
jsonwang 3 rokov pred
rodič
commit
f490e225ac

+ 1 - 0
BFRecordScreenKit.podspec

@@ -46,6 +46,7 @@ TODO: Add long description of the pod here.
   s.dependency 'BFCommonKit'
   s.dependency 'BFNetRequestKit'
   s.dependency 'BFMaterialKit'
+  s.dependency 'BFAnalyzeKit'
   s.dependency 'BFMediaKit'
   s.dependency 'BFUIKit'
   s.dependency 'GPUImage'

+ 97 - 96
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -63,30 +63,33 @@ public class BFRecordScreenController: BFBaseViewController {
         }
     }
 
-    var currentAssetProgress: CMTime = .zero    // 当前素材播放的进度
-    var recordStartTime: Double = 0             // 录制开始时间
-    var pauseTime : Double = 0                  // 停止无操作的时间点
+    var currentAssetProgress: CMTime = .zero // 当前素材播放的进度
+    // 播放器开始播放时间
+    var recordStartPlayTime: CMTime = .zero
+    var recordStartTime: Double = 0 // 录制开始时间
+    var pauseTime: Double = 0 // 停止无操作的时间点
 
-    var assetPlayer: AVPlayer?                  // 原视频音频播放器
+    var assetPlayer: AVPlayer? // 原视频音频播放器
 
-    var hadPrepareToPlayRecord = false          // 录音播放器准备
-    var recordPlayer : AVPlayer?                // 录音音频播放器
-    var movie : GPUImageMovie?                  // 视频预览
-    var playView : GPUImageView?                // 视频展示视图
+    var hadPrepareToPlayRecord = false // 录音播放器准备
+    var recordPlayer: AVPlayer? // 录音音频播放器
+    var movie: GPUImageMovie? // 视频预览
+    var playView: GPUImageView? // 视频展示视图
 
     // MARK: 行为参数
+
     var movieIsProcessing = false
-    var events = [WithDrawModel]()              // 行为记录,方便撤销
-    var isDragingProgressSlder : Bool = false // 是否在拖动进度条
+    var events = [WithDrawModel]() // 行为记录,方便撤销
+    var isDragingProgressSlder: Bool = false // 是否在拖动进度条
     var isStopAtRecordRange = -1
 
     // 保存识别出来的字幕信息,用于回放,和合成使用
 //    var saveSubTitles:[PQEditSubTitleModel] = Array.init()
-    
-    //MARK: - 录音相关
+
+    // MARK: - 录音相关
 
     // 定义音频的编码参数
-    let recordSettings : [String: Any] = [AVSampleRateKey: 44100.0, // 声音采样率
+    let recordSettings: [String: Any] = [AVSampleRateKey: 44100.0, // 声音采样率
                                          AVFormatIDKey: kAudioFormatLinearPCM, // 编码格式
                                          AVNumberOfChannelsKey: 1, // 采集音轨
                                          AVEncoderBitDepthHintKey: 16, // 位深
@@ -117,7 +120,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))
@@ -126,7 +129,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
@@ -140,11 +143,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.addCorner(corner: 6)
         btn.adjustsImageWhenHighlighted = false
         btn.addTarget(self, action: #selector(startRecord), for: .touchDown)
         btn.addTarget(self, action: #selector(endRecord), for: .touchUpInside)
@@ -152,18 +155,18 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var deleteRecordBtn : UIButton = {
+    lazy var deleteRecordBtn: UIButton = {
         let btn = UIButton(type: .custom)
         btn.backgroundColor = .red
         btn.setTitle("删除录制", for: .normal)
         btn.adjustsImageWhenHighlighted = false
-        btn.addCorner(corner:6)
+        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)
@@ -176,7 +179,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)
@@ -189,7 +192,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return btn
     }()
 
-    lazy var toolV : BFIntroduceToolView = {
+    lazy var toolV: BFIntroduceToolView = {
         let toolV = BFIntroduceToolView()
         toolV.centerY = view.centerY
 
@@ -206,14 +209,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)
@@ -221,7 +224,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)
@@ -229,7 +232,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)
@@ -237,7 +240,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)
@@ -245,14 +248,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
 
@@ -260,7 +263,7 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     // 显示字幕
-    lazy var subtitleLabel : PQSubTitleLabel = {
+    lazy var subtitleLabel: PQSubTitleLabel = {
         let subtitleLabel = PQSubTitleLabel()
         subtitleLabel.textAlignment = .center
         subtitleLabel.numberOfLines = 0
@@ -272,12 +275,12 @@ 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
+        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
@@ -286,10 +289,8 @@ public class BFRecordScreenController: BFBaseViewController {
         return audioSettingView
     }()
 
-    // 录音识别文字
-//    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
@@ -305,7 +306,6 @@ public class BFRecordScreenController: BFBaseViewController {
                 }
                 if !sself.isDragingProgressSlder {
                     BFLog(1, message: "isDragingProgressSlder 进行中")
-
                 }
                 sself.isDragingProgressSlder = true
 
@@ -326,7 +326,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return vv
     }()
 
-    lazy var collectionView : UICollectionView = {
+    lazy var collectionView: UICollectionView = {
         let flowLayout = UICollectionViewFlowLayout()
         flowLayout.minimumLineSpacing = 0
         flowLayout.minimumInteritemSpacing = 0
@@ -381,10 +381,13 @@ public class BFRecordScreenController: BFBaseViewController {
         // add by ak 取 nsl token
         BFRecordScreenViewModel.getNlsAccessToken { [weak self] token, appkey in
             BFLog(message: "nls appkey is \(appkey), token is \(token)")
+
             self?.recorderManager = BFVoiceRecordManager.init(token: token, appid: appkey)
         
+            //取消
             self?.recorderManager?.cancelRecordHandle = { _ in
             }
+            
             self?.recorderManager?.recorderProgrossHandle = {[weak self] progress in
                 BFLog(1, message: "curr:录音进度--\(progress) \(self?.recordStartTime ) \(self?.isRecording)")
                 if self?.indirectionView == nil {
@@ -526,7 +529,6 @@ public class BFRecordScreenController: BFBaseViewController {
             BFLog(message: "新录制完成::::\(materialsModel?.locationPath ?? "")")
         }
 
-
         // 字幕设置回调
         // 设置默认值
         setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
@@ -797,9 +799,7 @@ public class BFRecordScreenController: BFBaseViewController {
             itemModels[currItemModelIndex].voiceStickers.remove(at: isStopAtRecordRange)
             events.append(WithDrawModel(type: 3, timestamp: currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)]))
             indirectionView?.deleteItem(index: isStopAtRecordRange)
-//            drawOrUpdateRecordProgessLable()
             searchStopAtRecordRange()
-
             deleteTitles(voiceModel: model)
         }
     }
@@ -809,7 +809,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
         // 停止进度条滚动
         if isDragingProgressSlder {
-             return
+            return
         }
 
         pause()
@@ -822,6 +822,7 @@ public class BFRecordScreenController: BFBaseViewController {
         }
         
         let model = PQVoiceModel()
+        // 开始时间
         model.startTime = currentAssetProgress.seconds
         model.volume = 100
         recorderManager?.voiceModel = model
@@ -831,21 +832,22 @@ public class BFRecordScreenController: BFBaseViewController {
         }
         // 添加撤销记录点
         events.append(WithDrawModel(type: 2, timestamp: model.startTime))
-  
+
+        isRecording = true
+
 
         if !avatarView.isHidden {
             avatarView.beginRecord()
         }
- 
+
         if itemModels[currItemModelIndex].mediaType == .VIDEO {
-            
             if !movieIsProcessing {
                 movie?.startProcessing()
                 movieIsProcessing = true
             }
             assetPlayer?.volume = 0
             assetPlayer?.play()
-            
+
             // 暂停状态
             (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = true
         }
@@ -924,8 +926,6 @@ public class BFRecordScreenController: BFBaseViewController {
                         itemModels[currItemModelIndex].titleStickers.insert(titleTuple.0, at: titleTuple.1)
                     }
                 }
-
-//                drawOrUpdateRecordProgessLable()
             } else {}
             events.removeLast()
             let dur = itemModels[currItemModelIndex].materialDuraion
@@ -998,18 +998,18 @@ public class BFRecordScreenController: BFBaseViewController {
 
         if elems.count > 0 {
             //  TODO: 停在了录音区间,显示删除按钮
-            if fabs(elems[0].1.endTime - self.currentAssetProgress.seconds) < 0.5 {
+            if fabs(elems[0].1.endTime - 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 {
+            } else {
+                if fabs(elems[0].1.startTime - currentAssetProgress.seconds) < 0.5 {
                     BFLog(1, message: "吸附在录音开始")
 //                    changeWithDrawBtnLayout(true)
                     changeProgress(progress: Float(elems[0].1.startTime / itemModels[currItemModelIndex].materialDuraion))
@@ -1018,7 +1018,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 deleteRecordBtn.isHidden = false
                 recordBtn.isHidden = true
                 isStopAtRecordRange = elems.first!.0
-                
+
                 BFLog(1, message: "停在了录音区间里 \(isStopAtRecordRange)")
             }
         } else {
@@ -1082,15 +1082,18 @@ public class BFRecordScreenController: BFBaseViewController {
         if currentPlayRecordIndex == -3 { // 刚录音完,不需要播放
             return
         }
-
+        let type = itemModels[currItemModelIndex].mediaType
         let (shouldPlayRecordIndex, recordedAudio) = itemModels[currItemModelIndex].voiceStickers.enumerated().first { model in
-            model.1.endTime > CMTimeGetSeconds(currentT)
+            if type == .IMAGE {
+                return model.1.startTime >= CMTimeGetSeconds(currentT)
+            } else {
+               return model.1.endTime > CMTimeGetSeconds(currentT)
+            }
         } ?? (-1, nil)
 
         guard let recordedAudio = recordedAudio else {
             return
         }
-
         BFLog(1, message: "当前时间:\(CMTimeGetSeconds(currentT)), 找到的音频:\(recordedAudio.startTime), \(recordedAudio.endTime), \(recordedAudio.wavFilePath ?? "")")
 
         // 创建播放器
@@ -1160,7 +1163,6 @@ public class BFRecordScreenController: BFBaseViewController {
             }
         }
         BFLog(1, message: "应当播放:\(shouldPlayRecordIndex), 当前播放:\(currentPlayRecordIndex)")
-
     }
 
     func play() {
@@ -1172,7 +1174,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: .defaultToSpeaker)
                 try AVAudioSession.sharedInstance().setActive(true)
             } catch {}
-            
+
             BFLog(1, message: "开启session \(Date().timeIntervalSince(a))")
         }
         isNormalPlaying = true
@@ -1187,7 +1189,7 @@ public class BFRecordScreenController: BFBaseViewController {
             currentAssetProgress = CMTime.zero
         }
         if itemModels[currItemModelIndex].mediaType == .VIDEO {
-            assetPlayer?.volume = self.noSpeakVolume
+            assetPlayer?.volume = noSpeakVolume
             if !movieIsProcessing {
                 movie?.startProcessing()
                 movieIsProcessing = true
@@ -1205,7 +1207,7 @@ public class BFRecordScreenController: BFBaseViewController {
         //        movie?.cancelProcessing()
         assetPlayer?.pause()
         recordPlayer?.pause()
-        
+        recordStartPlayTime = CMTime.zero
         pauseTime = currentAssetProgress.seconds
 
         assetPlayer?.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000), completionHandler: { _ in
@@ -1215,7 +1217,6 @@ public class BFRecordScreenController: BFBaseViewController {
     }
 
     func fetchVideo() {
-        
         if assets.count > 0 {
             currItemModelIndex = 0
             for (index, asset) in assets.enumerated() {
@@ -1225,7 +1226,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 itemModels.append(itemModel)
                 if index == 0 {
                     if asset.mediaType == .video {
-                        itemModel.fetchAVUrlAsset = { [weak self, weak itemModel] uralss in
+                        itemModel.fetchAVUrlAsset = { [weak self, weak itemModel] _ in
 //                            self?.export(avsss:uralss)
                             DispatchQueue.main.async { [weak self] in
                                 self?.progressThumV.recordItem = itemModel
@@ -1328,11 +1329,11 @@ public class BFRecordScreenController: BFBaseViewController {
                 BFLog(1, message: "curr:\(CMTimeGetSeconds(currentAssetProgress))")
                 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)
-//                    BFLog(1, message: "进度监控:isDragingProgressSlder-\(self?.isDragingProgressSlder ?? false), isRecording - \(self?.isRecording ?? false), isNormalPlaying - \(self?.isNormalPlaying ?? false), su - \(su)")
+                    let su = !(self?.isDragingProgressSlder ?? false) || (self?.isRecording ?? false) || (self?.isNormalPlaying ?? false)
                     if su {
                         self?.progressThumV.progress = time.seconds
                     }
+                    // 更新字幕
                     self?.updateSubtitle(time: time)
                 }
             }
@@ -1353,20 +1354,19 @@ public class BFRecordScreenController: BFBaseViewController {
     }
 
     // MARK: - 录音对应图像绘制
-    
+
     // 撤销按钮修改title,重绘
-    func changeWithDrawBtnLayout(_ recorded:Bool) {
+    func changeWithDrawBtnLayout(_ recorded: Bool) {
         if recorded {
             withDrawBtn.setTitle("撤销录制", for: .normal)
-        }else {
+        } 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()
-        
     }
 
     // 通过缩略图进度条控制播放进度
@@ -1390,7 +1390,7 @@ public class BFRecordScreenController: BFBaseViewController {
             }
         }
     }
-
+ 
     func drawOrUpdateRecordProgessLable() {
         DispatchQueue.main.async { [weak self] in
             guard let sself = self else {
@@ -1418,27 +1418,27 @@ public class BFRecordScreenController: BFBaseViewController {
             }
         }
     }
-    
-    func reloadMaterial(recordItem : BFRecordItemModel) {
-        
+  
+    func reloadMaterial(recordItem: BFRecordItemModel) {
+
         if let path = recordItem.localPath, let lastCell: BFImageCoverViewCell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
-            
             setVideoPlay(item: recordItem.playItem, imageView: lastCell.playView)
             setAudioPlay(item: recordItem.playItem)
-            
+
             let degress = degressFromVideoFile(url: URL(fileURLWithPath: path))
-            switch (degress) {
+            switch degress {
             case 90:
-                lastCell.playView.setInputRotation(GPUImageRotationMode.init(rawValue: 2), at: 0)
+                lastCell.playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
             case 180:
-                lastCell.playView.setInputRotation(GPUImageRotationMode.init(rawValue: 7), at: 0)
+                lastCell.playView.setInputRotation(GPUImageRotationMode(rawValue: 7), at: 0)
             case 270:
-                lastCell.playView.setInputRotation(GPUImageRotationMode.init(rawValue: 1), at: 0)
+                lastCell.playView.setInputRotation(GPUImageRotationMode(rawValue: 1), at: 0)
             default:
-                break;
+                break
             }
         }
     }
+
 }
 
 extension BFRecordScreenController: GPUImageMovieDelegate {
@@ -1458,11 +1458,11 @@ extension BFRecordScreenController: AVAudioPlayerDelegate {
     public func audioPlayerDidFinishPlaying(_: AVAudioPlayer, successfully _: Bool) {
         BFLog(1, message: "录音播放结束")
     }
-  
 }
 
 
 
+
 // MARK: - UICollectionViewDelegate
 
 /// UICollectionViewDelegate
@@ -1511,7 +1511,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             // 暂停状态
             let lastCell: BFImageCoverViewCell? = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell
             lastCell?.playBtn.isSelected = false
-            
+
             let recordItem = itemModels[page]
             // 重绘录音区域
             indirectionView?.resetAllSubViews(items: recordItem.voiceStickers, percenWidth: recordItem.mediaType == .IMAGE ? progressThumV.thumbImageWidth / 2.0 : 0, totalDuration: recordItem.materialDuraion)
@@ -1524,8 +1524,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             assetPlayer?.seek(to: CMTime.zero)
             recordPlayer?.seek(to: CMTime.zero)
             if recordItem.mediaType == .VIDEO {
-                self.reloadMaterial(recordItem: recordItem)
-                                
+                reloadMaterial(recordItem: recordItem)
                 assetPlayer?.seek(to: .zero, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000))
             }
             if changeItemHandle != nil {
@@ -1534,13 +1533,12 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             // 重设撤销栈
             itemModels[currItemModelIndex].events = events
             events = itemModels[page].events
-            if let cell = collectionView.visibleCells.first as? BFImageCoverViewCell{
+            events.append(WithDrawModel(type: 0, timestamp: 0))
+            if let cell = collectionView.visibleCells.first as? BFImageCoverViewCell {
                 playBtn = cell.playBtn
             }
-            
             // 更新当前page
             currItemModelIndex = page
-//            drawOrUpdateRecordProgessLable()
         }
     }
 
@@ -1565,14 +1563,17 @@ public extension BFRecordScreenController {
             }
             isNormalPlaying = true
             playRecord(at: currentAssetProgress, periodicTimeObserver: { [weak self] currentT, currentItem in
-                BFLog(message: "播放段进度:\(currentT),\(currentItem)")
-                self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT) / 2)
-            }, didPlayToEndTime: { [weak self] recordedAudio, currentItem in
-                BFLog(message: "播放一段结束:\(String(describing: recordedAudio)),\(String(describing: currentItem))")
-                if (recordedAudio?.endTime ?? 0) >= (self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last?.endTime ?? 0) {
+                BFLog(message: "播放段进度:\(currentT),\(currentItem)")
+                self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
+            }, didPlayToEndTime: { [weak self] recordItem, currentItem in
+                BFLog(message: "播放第段结束:\(String(describing: recordItem)),\(String(describing: currentItem))")
+                if (recordItem?.endTime ?? 0) >= (self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last?.endTime ?? 0) {
                     self?.isEndPlay = true
                     self?.pause()
                 } else {
+                    self?.currentAssetProgress = CMTime(seconds: recordItem?.endTime ?? 0, preferredTimescale: 1000)
+                    // 当开始播放时重置录音播放起始时间
+                    self?.recordStartPlayTime = self?.currentAssetProgress ?? CMTime.zero
                     self?.imageRecordPlay()
                 }
             }) { [weak self] _, _ in
@@ -1585,17 +1586,17 @@ public extension BFRecordScreenController {
 
     /// 处理图片素材录音
     func imageRecordProgress(isRecord: Bool = false, progress: Float64) {
-        BFLog(message: "图片录音进度:\(progress)")
         if isRecord {
             currentAssetProgress = CMTime(seconds: itemModels[currItemModelIndex].materialDuraion + progress, preferredTimescale: 1000)
         } else {
-            currentAssetProgress = CMTime(seconds: progress, preferredTimescale: 1000)
+            currentAssetProgress = CMTime(seconds: recordStartPlayTime.seconds + progress, preferredTimescale: 1000)
         }
+        BFLog(message: "图片录音进度:\(progress),currentAssetProgress=\(currentAssetProgress),\(itemModels[currItemModelIndex].materialDuraion)")
         if itemModels[currItemModelIndex].mediaType == .IMAGE {
             DispatchQueue.main.async { [weak self] in
-                self?.progreddL.text = String(format: "%@", ((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress)).formatDurationToHMS())
-                self?.progressThumV.progress = ((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress))
-                self?.updateSubtitle(time: CMTime(value: CMTimeValue((self?.currentAssetProgress.seconds ?? 0) + (isRecord ? 0 : progress)), timescale: 1))
+                self?.progreddL.text = String(format: "%@", (self?.currentAssetProgress.seconds ?? 0).formatDurationToHMS())
+                self?.progressThumV.progress = (self?.currentAssetProgress.seconds ?? 0)
+                self?.updateSubtitle(time: self?.currentAssetProgress ?? CMTime.zero)
             }
         }
     }

+ 24 - 6
BFRecordScreenKit/Classes/RecordScreen/View/BFIndirectionProgressView.swift

@@ -14,7 +14,20 @@ class BFIndirectionProgressView: UIView {
     var indirecColor: UIColor = UIColor.clear
     var themeColor: UIColor = UIColor.hexColor(hexadecimal: "#28BE67")
     var progressHeight: CGFloat = 6
-    var percenWidth: CGFloat = 0
+    var tmpPercentW : CGFloat = 0
+    var percenWidth: CGFloat {
+        get {
+            if tmpPercentW <= 0 && totalDuration > 0 {
+                return frame.width / totalDuration
+            }else{
+                return  tmpPercentW
+            }
+            
+        }
+        set{
+            tmpPercentW = newValue
+        }
+    }
     var totalDuration: Float64 = 0
     var currentItem: UIView? // 当前的Item
 
@@ -29,9 +42,9 @@ class BFIndirectionProgressView: UIView {
         self.totalDuration = totalDuration
         self.progressHeight = progressHeight
         self.percenWidth = percenWidth
-        if self.percenWidth <= 0, totalDuration > 0 {
-            self.percenWidth = frame.width / totalDuration
-        }
+//        if self.percenWidth <= 0, totalDuration > 0 {
+//            self.percenWidth = frame.width / totalDuration
+//        }
     }
 
     required init?(coder _: NSCoder) {
@@ -41,6 +54,7 @@ class BFIndirectionProgressView: UIView {
     /// 重绘view
     /// - Parameter items: <#items description#>
     func resetAllSubViews(items: [PQVoiceModel]?, percenWidth: CGFloat = 0, totalDuration: Float64) {
+        frame.size.width = superview?.bounds.width ?? 0
         self.totalDuration = totalDuration
         self.percenWidth = percenWidth
         if self.percenWidth <= 0, totalDuration > 0 {
@@ -49,8 +63,9 @@ class BFIndirectionProgressView: UIView {
         subviews.forEach { vv in
             vv.removeFromSuperview()
         }
-        items?.forEach { model in
-            _ = createItemView(minX: model.startTime * percenWidth, width: (model.endTime - model.startTime) * percenWidth)
+ 
+        items?.forEach {[weak self] model in
+            _ = createItemView(minX: model.startTime * CGFloat(self?.percenWidth ?? 0), width: (model.endTime - model.startTime) * CGFloat(self?.percenWidth ?? 0))
         }
     }
 
@@ -61,6 +76,9 @@ class BFIndirectionProgressView: UIView {
     ///   - progress: <#progress description#>
     func setProgress(start: CGFloat = 0, progress: Float64) {
         BFLog(message: "录音进度--指示器Indir:progress=\(progress),duration=\(totalDuration),w=\(frame.width),perW=\(percenWidth),totalW:\(progress * percenWidth)")
+        if start * percenWidth >= frame.width {
+            frame.size.width = superview?.bounds.width ?? 0
+        }
         detectionAndCreateItem(start: start, progress: progress)
         currentItem?.frame.size.width = progress < 0 ? 0 : progress * percenWidth
         BFLog(message: "当前view:\(String(describing: currentItem))")

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

@@ -30,7 +30,7 @@ class BFVideoThumbProgressView: UIView {
     var dragStartHandle: (() -> Void)?
     var isDrag = false
 
-    let thumbImageWidth = 70.0
+    let thumbImageWidth : CGFloat = 70.0
 
     let fetchThumbStrategy: BFVideoThumbProgressStrategyProtocol = BFVideoThumbProgressStrategy()
 
@@ -75,6 +75,14 @@ class BFVideoThumbProgressView: UIView {
             make.width.equalTo(3)
             make.center.height.equalToSuperview()
         }
+        
+        progressView.contentView.addSubview(progessIndicateBackV)
+        progessIndicateBackV.snp.remakeConstraints { make in
+            make.left.equalTo(width * 0.5)
+            make.right.equalTo(width * -0.5)
+            make.bottom.equalToSuperview()
+            make.height.equalTo(6)
+        }
     }
 
     required init?(coder _: NSCoder) {
@@ -102,8 +110,9 @@ class BFVideoThumbProgressView: UIView {
         let date = Date()
         let dur = videoAsset.duration.seconds
         if dur > 0 {
-            let fps = Double(fetchThumbStrategy.frameNumberOfVideo(assetDuration: dur)) / dur
-            splitVideoFileUrlFps(urlAsset: videoAsset, fps: fps, firstImagesCount: 4) { [weak self] hadGetAll, images in
+            let count = fetchThumbStrategy.frameNumberOfVideo(assetDuration: dur)
+            let fps = Double(count) / dur
+            splitVideoFileUrlFps(urlAsset: videoAsset, fps: fps, firstImagesCount: Int(ceil(width/2.0/thumbImageWidth))) { [weak self] hadGetAll, images in
                 BFLog(1, message: "获取缩略图:\(hadGetAll), \(Date().timeIntervalSince(date))")
                 self?.recordItem!.thumbImgs.removeAll()
                 self?.recordItem!.thumbImgs.append(contentsOf: images)
@@ -125,7 +134,9 @@ class BFVideoThumbProgressView: UIView {
     func addThumbImages(images: [UIImage]) {
         DispatchQueue.main.async { [weak self] in
             self?.progressView.contentView.subviews.forEach { subview in
-                subview.removeFromSuperview()
+                if subview is UIImageView {
+                    subview.removeFromSuperview()
+                }
             }
             if images.count > 0 {
                 self?.thumbImgs = images
@@ -135,7 +146,7 @@ class BFVideoThumbProgressView: UIView {
                         let iv = UIImageView(image: img)
                         iv.contentMode = .scaleAspectFill
                         iv.clipsToBounds = true
-                        sself.progressView.contentView.addSubview(iv)
+                        sself.progressView.contentView.insertSubview(iv, belowSubview: sself.progessIndicateBackV)
                         iv.snp.makeConstraints { make in
                             make.left.equalTo(CGFloat(i) * CGFloat(sself.thumbImageWidth) + sself.width * 0.5)
                             make.top.bottom.equalToSuperview()
@@ -148,13 +159,13 @@ class BFVideoThumbProgressView: UIView {
                         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)
-                    }
+//                    sself.progressView.contentView.addSubview(sself.progessIndicateBackV)
+//                    sself.progessIndicateBackV.snp.remakeConstraints { make in
+//                        make.left.equalTo(sself.width * 0.5)
+//                        make.right.equalTo(sself.width * -0.5)
+//                        make.bottom.equalToSuperview()
+//                        make.height.equalTo(6)
+//                    }
                 }
             }
         }
@@ -162,7 +173,8 @@ class BFVideoThumbProgressView: UIView {
 
     func appendThumb(progress: Double = 0) {
         let count: Int = Int(progress / 2)
-        if recordItem?.mediaType == .IMAGE, thumbImgs.count < (count - 5) {
+        BFLog(message: "需要的图片个数:progress=\(progress),count=\(count)")
+        if recordItem?.mediaType == .IMAGE, (thumbImgs.count - 5) < count {
             guard let image = recordItem?.coverImg else {
                 return
             }