Browse Source

录制页可增加素材

harry 3 years ago
parent
commit
fb25ce52e8

+ 27 - 17
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenCameraManager.swift

@@ -33,14 +33,15 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
     var cameraProgressV: BFCameraProgressView?
     
     // 录制完成回调
-    var recordEndCallBack: recordEndCallBack?
+    var hasInitCallBack : (()->Void)?
+    var recordEndCallBack : recordEndCallBack?
     var recordProgressCallBack : ((CMTime) -> Void)?
     
     var startTime = Date()
     var videoModel = PQEditVisionTrackMaterialsModel()
     
     // 用于打开摄像头初始流程
-    var firstOpenCamera : Bool = true
+    static var firstOpenCamera : Bool = true
     //当前录制的缩略图数量
     var currVideoThumImagesNum = 0
     //当前摄像的序号
@@ -66,6 +67,8 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
             return
         }
         cameraProgressV?.recordItem = recordItem
+        cameraProgressV?.collectionV.reloadData()
+        cameraProgressV?.isHidden = true
         currVideoIndex = 0
 
         camera.startCapture()
@@ -74,13 +77,13 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         camera.addTarget(filter)
         filter.addTarget(rendView)
         
-        if firstOpenCamera {
+        if BFRecordScreenCameraManager.firstOpenCamera {
             startRecord()
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in
                 guard let wself = self else { return }
 
                 wself.endRecord()
-                wself.firstOpenCamera = false
+                BFRecordScreenCameraManager.firstOpenCamera = false
             })
         }
     }
@@ -105,7 +108,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         
         
         // 为了第一时间能更新collection view数据
-        if !firstOpenCamera{
+        if !BFRecordScreenCameraManager.firstOpenCamera{
             recordItem?.videoStickers.append(videoModel)
             progreddL?.isHidden = false
             cameraProgressV?.isHidden = false
@@ -114,7 +117,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         
         timerr = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: {[weak self] _ in
             guard let wself = self else { return }
-            if wself.firstOpenCamera {
+            if BFRecordScreenCameraManager.firstOpenCamera {
                 return
             }
             //MARK: 进度计时器
@@ -135,7 +138,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         timerr?.invalidate()
         timerr = nil
         BFLog(1, message: " 拍摄时长 \(Date().timeIntervalSince(startTime))")
-        let su = firstOpenCamera
+        let su = BFRecordScreenCameraManager.firstOpenCamera
         movieWrite?.finishRecording(completionHandler: {[weak self] in
             guard let wself = self else { return }
             
@@ -143,20 +146,13 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
                 if !su {
                     if let finalPath = PQBridgeObject.p_setupFileRename(vpath), finalPath.count > 0 {
                         let dur = AVURLAsset(url: URL(fileURLWithPath: finalPath))
-                        BFLog(1, message: "拍摄文件时长: \(dur.duration.seconds)")
                         wself.videoModel.timelineOut = wself.videoModel.timelineIn + dur.duration.seconds
+                        BFLog(1, message: "拍摄文件时长:\(wself.videoModel.timelineIn)~\(wself.videoModel.timelineOut),  \(dur.duration.seconds)")
                         wself.videoModel.locationPath = finalPath
                         wself.currentAssetProgress = CMTime(seconds: wself.videoModel.timelineOut, preferredTimescale: 1000)
                     }else{
                         // 录制失败后恢复原样
-                        wself.videoModel.timelineOut = wself.videoModel.timelineIn
-                        wself.currentAssetProgress = CMTime(seconds: wself.videoModel.timelineOut, preferredTimescale: 1000)
-                        wself.recordItem?.thumbImgs.removeAll(where: { img in
-                            wself.videoModel.thumImgs?.contains(img) ?? false
-                        })
-                        wself.videoModel.thumImgs?.removeAll()
-                        
-                        wself.addNewThumb()
+                        wself.revertLast()
                         cShowHUB(superView: nil, msg: "录制失败,未能生成文件")
                     }
                     DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
@@ -164,6 +160,8 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
                     }
                     wself.recordEndCallBack?(true, wself.videoModel)
 
+                }else{
+                    wself.hasInitCallBack?()
                 }
             }
             
@@ -172,6 +170,18 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         })
     }
     
+    // 录制失败 , 不足一秒时恢复上一次状态
+    func revertLast(){
+        videoModel.timelineOut = videoModel.timelineIn
+        currentAssetProgress = CMTime(seconds: videoModel.timelineOut, preferredTimescale: 1000)
+        recordItem?.thumbImgs.removeAll(where: { img in
+            videoModel.thumImgs?.contains(img) ?? false
+        })
+        videoModel.thumImgs?.removeAll()
+        
+        cameraProgressV?.collectionV.reloadData()
+    }
+    
     override func play() {
         camera?.pauseCapture()
     }
@@ -229,7 +239,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
 
 extension BFRecordScreenCameraManager : GPUImageVideoCameraDelegate {
     func willOutputSampleBuffer(_ sampleBuffer: CMSampleBuffer!) {
-        if !recording || firstOpenCamera {
+        if !recording || BFRecordScreenCameraManager.firstOpenCamera {
             return
         }
         let dur = CMTime(seconds: movieWrite?.duration.seconds ?? 0, preferredTimescale: 1000)

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

@@ -41,12 +41,14 @@ public class BFRecordScreenController: BFBaseViewController {
         let m = BFRecordScreenVideoManager()
         m.assetPlayer = assetPlayer
         m.recordPlayer = recordPlayer
+        m.dele = self
         return m
     }()
     
     lazy var rsimanager : BFRecordScreenImageManager = {
         let m = BFRecordScreenImageManager()
         m.recordPlayer = recordPlayer
+        m.dele = self
         return m
     }()
     
@@ -56,6 +58,10 @@ public class BFRecordScreenController: BFBaseViewController {
             guard let wself = self else { return }
             wself.currentAssetProgress = progress
         }
+        m.hasInitCallBack = {[weak self] in
+            guard let wself = self else { return }
+            wself.recordBtn.isEnabled = true
+        }
         return m
     }()
     var rscurrentManager = BFRecordScreenBaseManager()
@@ -63,9 +69,9 @@ public class BFRecordScreenController: BFBaseViewController {
     // MARK: - 录制参数
     public var assets = [PHAsset]()
     
-    var currItemModelIndex = -1 {
+    var currItemModelIndex = 0 {
         didSet{
-            if currItemModelIndex < 0 {
+            if currItemModelIndex < 0 || currItemModelIndex >= itemModels.count{
                 return
             }
             let itemModel = itemModels[currItemModelIndex]
@@ -90,11 +96,12 @@ public class BFRecordScreenController: BFBaseViewController {
             case .Camera:
                 rscurrentManager = rscmanager
                 recordBtn.setTitle("按住 录音", for: .normal)
+                recordBtn.isEnabled = false
                 progressThumV.isHidden = true
                 cameraProgressThumV.isHidden = false
                 progreddL.isHidden = true
                 rscmanager.cameraProgressV = cameraProgressThumV
-
+                
             default:
                 break
             }
@@ -143,7 +150,7 @@ public class BFRecordScreenController: BFBaseViewController {
     //    var shouldPlayRecordIndex:Int = -1          // 当前应该播放的录音资源序号
     var currentPlayRecordIndex: Int = -1 // >= 0 :当前正在播放的录音资源序号; -3: 刚录音完,不需要播放录音; -1:初始化阶段
     public var displayLink: CADisplayLink? // 图片素材播放控制
-    var isRecording = false { // 是否正在录音
+    public var isRecording = false { // 是否正在录音
         didSet {
             withDrawBtn.isHidden = isRecording
             changeVoiceBtn.isHidden = isRecording
@@ -160,7 +167,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
     var isEndPlay = false
 
-    var isNormalPlaying = false { // 是否正在播放
+    public var isNormalPlaying = false { // 是否正在播放
         didSet {
             withDrawBtn.isHidden = isNormalPlaying
         }
@@ -244,7 +251,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return l
     }()
 
-    lazy var playBtn: UIButton = {
+    public lazy var playBtn: UIButton = {
         let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 150, height: 156))
         btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
         let vv = UIView(frame: CGRect(x: 0, y: 0, width: 0.5, height: 0.5))
@@ -531,7 +538,7 @@ public class BFRecordScreenController: BFBaseViewController {
     
     public override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
-        endScrollItem(collectionView)
+//        endScrollItem(page: max(currItemModelIndex, 0))
         // 设置默认值
         setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
     }
@@ -567,9 +574,7 @@ public class BFRecordScreenController: BFBaseViewController {
         
         view.backgroundColor = .black
         view.addSubview(collectionView)
-        
-        fetchVideo()
-        
+                
         view.addSubview(bottomeView)
 //        view.addSubview(subtitleLabel)
         view.addSubview(playBtn)
@@ -624,8 +629,13 @@ public class BFRecordScreenController: BFBaseViewController {
         }
 
         layoutsubview()
-
         view.addSubview(subtitleEditView)
+        
+//        DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {[weak self] in
+//            guard let wself = self else { return }
+//            
+//            wself.endScrollItem(page: 0)
+//        }
 
         if !SWNetRequest.isNetReachabled() {
             cShowHUB(superView: view, msg: "网络不佳,字幕可能无法生成")
@@ -750,12 +760,12 @@ public class BFRecordScreenController: BFBaseViewController {
                         if tempVoice != nil {
                             tempItem = item
                         }
-                        BFLog(3, message: "字幕回调-找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? ""),index=\(index)")
+//                        BFLog(3, message: "字幕回调-找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? ""),index=\(index)")
                     }
                 }
                 // 2:如果通过titleTaskId没找到录音文件,则通过
                 if tempVoice == nil && (self?.isRecording ?? false) && self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last?.recordId == nil {
-                    BFLog(3, message: "字幕回调-如果通过titleTaskId没找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? "")")
+//                    BFLog(3, message: "字幕回调-如果通过titleTaskId没找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? "")")
                     tempVoice = self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last
                 }
                 // 3:如果通过titleTaskId跟audioFilePath都没找到录音文件,则默认为recorderManager?.voiceModel
@@ -764,7 +774,7 @@ public class BFRecordScreenController: BFBaseViewController {
                     return
                 }
                 guard let currentItem = tempItem ?? self?.itemModels[self?.currItemModelIndex ?? 0] else {
-                    BFLog(3, message: "字幕回调-最终没找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? "")")
+//                    BFLog(3, message: "字幕回调-最终没找到录音文件:taskID=\(recordId ),audioFilePath=\(audioFilePath ?? "")")
                     return
                 }
                 newSubtitle.timelineIn = currentVoice.startCMTime + CMTime(seconds: Float64((((payload?["begin_time"]) as? Int) ?? 0) + 300) / 1000.0, preferredTimescale: 1000)
@@ -790,7 +800,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 // 加入到语音数组里
 
                 model.endCMTime = wself.currentAssetProgress
-                BFLog(1, message: "录音地址:\((model.wavFilePath ?? "").replacingOccurrences(of: documensDirectory, with: "")) -  \(model.startCMTime.seconds)~\(model.endCMTime.seconds), dur: \(model.endCMTime.seconds - model.startCMTime.seconds) / \(model.duration)")
+                BFLog(1, message: "录音地址:\((model.wavFilePath ?? "").replacingOccurrences(of: documensDirectory, with: "")) -  \(model.startCMTime.seconds)~\(model.endCMTime.seconds), dur: \(model.endCMTime.seconds - model.startCMTime.seconds)")
                 /// 注:录音机回调的录音时长大于一秒,而业务逻辑计算的会小于一秒
                 if (model.endCMTime.seconds - model.startCMTime.seconds) < 1 {
                     // 取消录制
@@ -839,7 +849,7 @@ public class BFRecordScreenController: BFBaseViewController {
                                 item.startCMTime = CMTime(seconds: wself.itemModels[wself.currItemModelIndex].voiceStickers[index - 1].endCMTime.seconds, preferredTimescale: 1000)
                                 item.endCMTime = CMTime(seconds: item.startCMTime.seconds + tempDuration, preferredTimescale: 1000)
                             }
-                            BFLog(message: "录制结束重新排序录音文件:\(index)-\(item.wavFilePath ?? "")-\(item.startCMTime.seconds)-\(item.endCMTime.seconds)-\(item.endCMTime.seconds - item.startCMTime.seconds)")
+                            BFLog(1, message: "录制结束重新排序录音文件:\(index)-\(item.wavFilePath ?? "")-\(item.startCMTime.seconds)-\(item.endCMTime.seconds)-\(item.endCMTime.seconds - item.startCMTime.seconds)")
                         }
                     }
                 }
@@ -930,41 +940,45 @@ public class BFRecordScreenController: BFBaseViewController {
             }
             return
         }
-
-        if showSubtitleIndex > -1, showSubtitleIndex < itemModels[currItemModelIndex].titleStickers.count {
-            let currShowSubtitle = itemModels[currItemModelIndex].titleStickers[showSubtitleIndex]
-
-            if CMTimeCompare(currShowSubtitle.timelineIn, time) <= 0, CMTimeCompare(currShowSubtitle.timelineOut, time) > 0 {
-                // 已存在字幕
-                if subtitleLabel.text != currShowSubtitle.text {
-                    subtitleLabel.text = currShowSubtitle.text
-                    setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
+        
+        if let recordItem = rscurrentManager.recordItem {
+            
+            if showSubtitleIndex > -1, showSubtitleIndex < recordItem.titleStickers.count {
+                let currShowSubtitle = recordItem.titleStickers[showSubtitleIndex]
+                
+                if CMTimeCompare(currShowSubtitle.timelineIn, time) <= 0, CMTimeCompare(currShowSubtitle.timelineOut, time) > 0 {
+                    // 已存在字幕
+                    if subtitleLabel.text != currShowSubtitle.text {
+                        subtitleLabel.text = currShowSubtitle.text
+                        setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
+                    }
+                    return
                 }
-                return
+                showSubtitleIndex = -1
             }
-            showSubtitleIndex = -1
-        }
-
-        var findShowSubtitle: PQEditSubTitleModel?
-        for (index, subtitle) in itemModels[currItemModelIndex].titleStickers.enumerated() {
-            if CMTimeCompare(subtitle.timelineIn, time) <= 0, CMTimeCompare(subtitle.timelineOut, time) > 0, subtitle.audioFilePath.count > 0 { //  audioFilePath.count 这个条件是确保这个字幕有对应录音
-                findShowSubtitle = subtitle
-//                BFLog(1, message: "找到要显示的字幕 in \((findShowSubtitle?.timelineIn ?? .zero).seconds) out \((findShowSubtitle?.timelineOut ?? .zero).seconds) text:\(findShowSubtitle?.text ?? "") currTime is \(CMTimeGetSeconds(time))")
-                showSubtitleIndex = index
-                break
+            
+            var findShowSubtitle: PQEditSubTitleModel?
+            for (index, subtitle) in recordItem.titleStickers.enumerated() {
+                if CMTimeCompare(subtitle.timelineIn, time) <= 0, CMTimeCompare(subtitle.timelineOut, time) > 0, subtitle.audioFilePath.count > 0 { //  audioFilePath.count 这个条件是确保这个字幕有对应录音
+                    findShowSubtitle = subtitle
+                    //                BFLog(1, message: "找到要显示的字幕 in \((findShowSubtitle?.timelineIn ?? .zero).seconds) out \((findShowSubtitle?.timelineOut ?? .zero).seconds) text:\(findShowSubtitle?.text ?? "") currTime is \(CMTimeGetSeconds(time))")
+                    showSubtitleIndex = index
+                    break
+                }
             }
-        }
-
-        if findShowSubtitle != nil, subtitleLabel.text != findShowSubtitle!.text {
-            subtitleLabel.text = findShowSubtitle!.text
-            setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
-
-        } else {
-            if subtitleLabel.text?.count ?? 0 > 0 {
-                subtitleLabel.text = ""
-                subtitleLabel.backgroundColor = UIColor.clear
+            
+            if findShowSubtitle != nil, subtitleLabel.text != findShowSubtitle!.text {
+                subtitleLabel.text = findShowSubtitle!.text
+                setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
+                
+            } else {
+                if subtitleLabel.text?.count ?? 0 > 0 {
+                    subtitleLabel.text = ""
+                    subtitleLabel.backgroundColor = UIColor.clear
+                }
             }
         }
+
     }
 
     /// 设置字幕样式和位置
@@ -1437,7 +1451,7 @@ public class BFRecordScreenController: BFBaseViewController {
         btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
     }
 
-    @objc func playVideo(btn: UIButton) {
+    @objc public func playVideo(btn: UIButton) {
         btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
 
         if itemModels[currItemModelIndex].mediaType == .Image && itemModels[currItemModelIndex].voiceStickers.count <= 0 {
@@ -1673,8 +1687,8 @@ public class BFRecordScreenController: BFBaseViewController {
             recordPlayer.pause()
             if let playItem = recordPlayer.currentItem {
                 NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: playItem)
-                recordPlayer.replaceCurrentItem(with: newItem)
             }
+            recordPlayer.replaceCurrentItem(with: newItem)
             
             recordPlayer.volume = 1
             currentPlayRecordIndex = -1
@@ -1827,7 +1841,7 @@ public class BFRecordScreenController: BFBaseViewController {
         recordBtn.isHidden = true
     }
 
-    func pause() {
+    public func pause() {
         BFLog(1, message: "暂停播放")
         isNormalPlaying = false
 
@@ -1856,40 +1870,44 @@ public class BFRecordScreenController: BFBaseViewController {
         rscurrentManager.pause()
     }
 
-    func fetchVideo() {
-        if assets.count > 0 {
-            for (index, asset) in assets.enumerated() {
+    public func fetchMaterial(_ phAsset:[PHAsset]) {
+        
+        var lastCount = itemModels.count
+
+        if lastCount > 0
+            && itemModels[lastCount-1].mediaType == .Camera
+            && itemModels[lastCount-1].voiceStickers.count == 0{
+            removeCameroCell()
+            lastCount -= 1
+        }
+        
+        var indexPaths = [IndexPath]()
+        
+        if phAsset.count > 0 {
+            for (index, asset) in phAsset.enumerated() {
                 let itemModel = BFRecordItemModel()
                 itemModel.index = index
-                itemModel.initOriginData(phasset: asset)
-                if asset.mediaType != .video {
-                    itemModel.coverPath = asset.localPath
+                if asset.title == "record.camera"{
+                    itemModel.mediaType = .Camera
+
+                }else{
+                    itemModel.initOriginData(phasset: asset)
+                    if asset.mediaType != .video {
+                        itemModel.coverPath = asset.localPath
+                    }
                 }
+                indexPaths.append(IndexPath(row: itemModels.count, section: 0))
                 itemModels.append(itemModel)
-//                if index == 0 {
-//                    if asset.mediaType == .video {
-//                        itemModel.fetchAVUrlAssetCallBack = { [weak self, weak itemModel] in
-//                            DispatchQueue.main.async { [weak self, weak itemModel] in
-////                                self?.progressThumV.recordItem = itemModel
-//                                self?.progressThumV.isHidden = false
-//                                self?.recordBtn.isEnabled = true
-//                            }
-//                        }
-//                    } else {
-//                        recordBtn.isEnabled = true
-//                    }
-//                }
             }
-        }else {
-            let itemModel = BFRecordItemModel()
-            itemModel.index = 0
-            itemModel.mediaType = .Camera
-            itemModels.append(itemModel)
+        }
+        collectionView.insertItems(at: indexPaths)
+        collectionView.contentOffset = CGPoint(x: cScreenWidth * CGFloat(lastCount) , y: 0.0)
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {[weak self] in
+            guard let wself = self else { return }
             
-            recordBtn.isEnabled = true
+            wself.endScrollItem(page: lastCount)
         }
-        collectionView.reloadData()
-
+        
         // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
         playBtn.isSelected = (itemModels.first?.mediaType != .Video && (itemModels.first?.voiceStickers.count ?? 0) <= 0)
         playBtn.isHidden = playBtn.isSelected
@@ -2151,38 +2169,82 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
 
     public func scrollViewWillBeginDragging(_: UIScrollView) {
         BFLog(1, message: "开始滚动")
+        if rscurrentManager.recordItem?.mediaType == .Camera && rscurrentManager.recordItem?.voiceStickers.count == 0{
+            collectionView.isScrollEnabled = false
+            showDeleteCamera()
+            return
+        }
         recordBtn.isEnabled = false
     }
+    
+    func showDeleteCamera(){
+        let alertV = UIAlertController(title: nil, message: "你还没有录制内容哦,切换段落将会取消录制,是否确定取消", preferredStyle: .alert)
+        let cancelAction = UIAlertAction(title: "取消", style: .default) {[weak self] _ in
+            guard let wself = self else { return }
+            wself.collectionView.isScrollEnabled = true
+        }
+        let okAction = UIAlertAction(title: "确定", style: .default) { [weak self] _ in
+            guard let wself = self else { return }
+            wself.collectionView.isScrollEnabled = true
+            wself.removeCameroCell()
+            wself.changeItemHandle?(-3)
+        }
+        alertV.addAction(cancelAction)
+        alertV.addAction(okAction)
+        
+        self.present(alertV, animated: true, completion: nil)
+    }
 
+    public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
+        let page = Int((targetContentOffset.pointee.x + scrollView.frame.width / 2) / scrollView.frame.width)
+        
+        if page != currItemModelIndex{
+            endScrollItem(page: page)
+        }
+
+        BFLog(1, message: "将要停止拖动, page:\(currItemModelIndex) -> \(page)")
+        
+    }
+    
     public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        endScrollItem(scrollView)
+        endScroll()
     }
-
+    
     public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
         if !decelerate {
-            endScrollItem(scrollView)
+            endScroll()
         }
     }
+    
+    func endScroll() {
+        recordBtn.isEnabled = true
+    }
+    
+    func removeCameroCell(){
+        itemModels.remove(at: currItemModelIndex)
+        UIView.performWithoutAnimation {
+            collectionView.deleteItems(at: [IndexPath(row: currItemModelIndex, section: 0)])
+        }
+        currItemModelIndex -= 1
+    }
 
-    func endScrollItem(_ scrollView: UIScrollView) {
-//    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
-        BFLog(1, message: "滚动结束")
-
-        let page = Int((scrollView.contentOffset.x + scrollView.frame.width / 2) / scrollView.frame.width)
-        if page != currItemModelIndex {
-            // 切换素材时先把录制状态切为不可用,延迟可点,避免在缩略图未加载出来时即可录制
-            currItemModelIndex = page
-            // 暂停
-            pause()
-            // 如果在录制中,停止录制
-            if isRecording {
-                endRecord()
-            }
-            recorderManager?.cancelTitleService()
-            
-            events = [WithDrawModel]()
 
-            let recordItem = itemModels[currItemModelIndex]
+    func endScrollItem(page: Int) {
+        BFLog(1, message: "endScrollItem")
+        // 切换素材时先把录制状态切为不可用,延迟可点,避免在缩略图未加载出来时即可录制
+        currItemModelIndex = page
+        // 暂停
+        pause()
+        // 如果在录制中,停止录制
+        if isRecording {
+            endRecord()
+        }
+        recorderManager?.cancelTitleService()
+        
+        events = [WithDrawModel]()
+        
+        
+        if let recordItem = rscurrentManager.recordItem {
             // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
             playBtn.isSelected = (recordItem.mediaType != .Video && recordItem.voiceStickers.count <= 0)
             playBtn.isHidden = playBtn.isSelected
@@ -2195,7 +2257,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
                 self?.recordBtn.isEnabled = true
             }
             // 更新缩略图
-//            progressThumV.isHidden = false
+            //            progressThumV.isHidden = false
             progreddL.text = "00:00"
             // 重置指针
             currentAssetProgress = .zero
@@ -2206,28 +2268,28 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             // 重置播放器
             assetPlayer.seek(to: CMTime.zero)
             recordPlayer.seek(to: CMTime.zero)
-
+            
             if let voice = itemModels[page].voiceStickers.enumerated().first(where: { m in
                 m.1.startTime == 0
             }) {
                 currentPlayRecordIndex = voice.0
             }
-
+            
             searchStopAtRecordRange()
             changeWithDrawBtnLayout(0)
             pauseTime = 0
-
+            
             if changeItemHandle != nil {
                 changeItemHandle!(page)
             }
-
+            
             // add by ak 切换后刷新字幕
             subtitleLabel.removeFromSuperview()
             let cell = collectionView.cellForItem(at: IndexPath(item: page, section: 0)) as? BFImageCoverViewCell
             cell?.contentView.addSubview(subtitleLabel)
             updateSubtitle(time: currentAssetProgress)
+            
         }
-        recordBtn.isEnabled = true
     }
 
     public func updateContentOffset(index: Int) {
@@ -2263,22 +2325,28 @@ public extension BFRecordScreenController {
                 self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
             }
         }, didPlayToEndTime: { [weak self] recordInfo, currentItem in
+            
+            guard let wself = self else { return }
+            
             BFLog(message: "播放录音结束:\(String(describing: recordInfo?.1)),\(String(describing: currentItem))")
-            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .Image {
-                if (self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.count ?? 0) <= ((recordInfo?.0 ?? 0) + 1) || CMTimeCompare((recordInfo?.1.endCMTime ?? .zero), (self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers.last?.endCMTime ?? .zero)) >= 0 {
+            if wself.itemModels[wself.currItemModelIndex ].mediaType == .Image {
+                if (wself.itemModels[wself.currItemModelIndex ].voiceStickers.count ) <= ((recordInfo?.0 ?? 0) + 1) || CMTimeCompare((recordInfo?.1.endCMTime ?? .zero), (wself.itemModels[wself.currItemModelIndex].voiceStickers.last?.endCMTime ?? .zero)) >= 0 {
                     
-                    self?.isEndPlay = true
-                    self?.pause()
+                    wself.isEndPlay = true
+                    wself.pause()
                     // 注:矫正进度--播放结束后当前指针应该到当前素材总时长
-                    self?.currentAssetProgress = CMTime(seconds: self?.itemModels[self?.currItemModelIndex ?? 0].materialDuraion.seconds ?? 0, preferredTimescale: 1000)
-                    self?.resetCurrentProgress()
+                    wself.currentAssetProgress = CMTime(seconds: wself.itemModels[wself.currItemModelIndex ].materialDuraion.seconds , preferredTimescale: 1000)
+                    wself.resetCurrentProgress()
                     // 录制播放结束后显示录制按钮
-                    self?.recordBtn.isHidden = false
-                    self?.recordBtn.alpha = 1
+                    wself.recordBtn.isHidden = false
+                    wself.recordBtn.alpha = 1
                 } else {
                     // 注:矫正进度--一段录音播放结束后当前指针应该到当前录音结束点
-                    self?.currentAssetProgress = self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers[(recordInfo?.0 ?? 0) + 1].startCMTime ?? .zero
-                    self?.startPlayRecord(time: self?.currentAssetProgress ?? CMTime.zero)
+                    let next = wself.itemModels[wself.currItemModelIndex ].voiceStickers[(recordInfo?.0 ?? 0) + 1].startCMTime
+                    if CMTimeCompare(next, wself.currentAssetProgress) > 0{
+                        wself.currentAssetProgress = next
+                    }
+                    wself.startPlayRecord(time: wself.currentAssetProgress )
                 }
             }
         }) { [weak self] _, _ in

+ 19 - 4
BFRecordScreenKit/Classes/RecordScreen/View/BFStripSwithView.swift

@@ -11,7 +11,7 @@ import UIKit
 
 open class BFStripSwithView: UIView {
     public var itemClickHandle: ((_ sender: UIButton, _ index: Int) -> Void)?
-    var currentIndex: Int = 0
+    public var currentIndex: Int = 0
     var itemSpace: CGFloat = 4
     var itemHeight: CGFloat = 6
     var itemNormalColor: UIColor = UIColor.hexColor(hexadecimal: "#FFFFFF", alpha: 0.3)
@@ -53,11 +53,25 @@ open class BFStripSwithView: UIView {
         super.layoutSubviews()
         addSubviews()
     }
+    
+    public func resetView(count:Int, space: CGFloat = 10, selectedIndex: Int? = nil){
 
-    private func addSubviews() {
-        if currentItem != nil {
-            return
+        if selectedIndex != nil, (selectedIndex ?? 0) < count {
+            currentIndex = selectedIndex!
         }
+        if count < strips{
+            currentIndex -= (strips - count)
+        }
+
+        strips = count
+
+        self.layoutIfNeeded()
+    }
+
+    private func addSubviews() {
+//        if currentItem != nil {
+//            return
+//        }
         subviews.forEach { view in
             view.removeFromSuperview()
         }
@@ -103,5 +117,6 @@ open class BFStripSwithView: UIView {
         UIView.animate(withDuration: 0.01) { [weak self] in
             self?.selectedBtn.center.x = CGFloat(sender!.center.x)
         }
+        currentIndex = index
     }
 }

+ 4 - 1
BFRecordScreenKit/Classes/RecordScreen/View/ProgressView/BFCameraProgressView.swift

@@ -97,11 +97,12 @@ extension BFCameraProgressView: UICollectionViewDelegateFlowLayout, UICollection
                 if let (ind, _) = sticker.thumImgs?.enumerated().first(where: { ele in
                     ele.1 == img
                 }) {
-                    size = CGSize(width: max(0, min((sticker.timelineOut / 5.0  -  CGFloat(ind))*70.0, 70.0)), height: 50.0)
+                    size = CGSize(width: max(0, min(((sticker.timelineOut - sticker.timelineIn) / 5.0  -  CGFloat(ind))*70.0, 70.0)), height: 50.0)
                 }
                 
                 if size.width < 0 {
                     BFLog(1, message: "ewrr")
+                    size = .zero
                 }
 
                 BFLog(1, message: "curr size - row:\(indexPath.row), \(size.width)")
@@ -123,6 +124,8 @@ extension BFCameraProgressView: UICollectionViewDelegateFlowLayout, UICollection
             let line = UIView()
             line.backgroundColor = ThemeStyleColor
             line.frame = CGRect(x: 0, y: 44, width: 70, height: 6)
+            cell.contentView.addSubview(line)
+
         }
         
         imgview?.image = recordItem?.thumbImgs[indexPath.row]

+ 1 - 1
BFRecordScreenKit/Classes/RecordScreen/View/ProgressView/BFVideoThumbProgressView.swift

@@ -59,7 +59,7 @@ class BFVideoThumbProgressView: BFProgressBaseView {
 
     override init(frame: CGRect) {
         super.init(frame: frame)
-        addSubview(progressView)
+        insertSubview(progressView, belowSubview: line)
         progressView.contentView.addSubview(progessIndicateBackV)
         progessIndicateBackV.snp.makeConstraints { make in
             make.left.equalTo(width * 0.5)