Jelajahi Sumber

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

jsonwang 3 tahun lalu
induk
melakukan
234638d503

+ 58 - 35
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -51,7 +51,6 @@ public class BFRecordScreenController: BFBaseViewController {
 
             recordBtn.setTitle(isRecording ? "松手 暂停" : "按住 录音", for: .normal)
             recordBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#389AFF", alpha: isRecording ? 0.6 : 1)
-            playBtn.isSelected = isRecording
 //            if !isRecording {
 //                BFLog(1, message: "stop")
 //            }
@@ -67,7 +66,6 @@ public class BFRecordScreenController: BFBaseViewController {
 
     var isNormalPlaying = false { // 是否正在播放
         didSet {
-            playBtn.isSelected = isNormalPlaying
             withDrawBtn.isHidden = isNormalPlaying
         }
     }
@@ -144,11 +142,13 @@ public class BFRecordScreenController: BFBaseViewController {
     }()
 
     lazy var playBtn: UIButton = {
-        let btn = UIButton(frame: view.bounds)
+        let btn = UIButton(frame: CGRect.init(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: 1, height: 1))
         btn.setImage(vv.graphicsGetImage(), for: .selected)
+        btn.setImage(nil, for: .highlighted)
         btn.addTarget(self, action: #selector(playVideo(btn:)), for: .touchUpInside)
+        btn.center = view.center
         return btn
     }()
 
@@ -184,7 +184,7 @@ public class BFRecordScreenController: BFBaseViewController {
         btn.setTitle("删除录制", for: .normal)
         btn.adjustsImageWhenHighlighted = false
         btn.addCorner(corner: 6)
-        btn.addTarget(self, action: #selector(deleteRecorded), for: .touchUpInside)
+        btn.addTarget(self, action: #selector(deleteRecordAction), for: .touchUpInside)
         btn.isHidden = true
         return btn
     }()
@@ -524,7 +524,7 @@ public class BFRecordScreenController: BFBaseViewController {
                     sself.itemModels[sself.currItemModelIndex].materialDuraion = Double(String(format: "%.3f", duration)) ?? 0
                     self?.isEndPlay = true
                     // 录制结束显示播放按钮
-                    (sself.collectionView.cellForItem(at: IndexPath(item: sself.currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = sself.itemModels[sself.currItemModelIndex].voiceStickers.count <= 0
+                    sself.playBtn.isSelected = sself.itemModels[sself.currItemModelIndex].voiceStickers.count <= 0
                 }
                 DispatchQueue.main.async { [weak self] in
                     // 录音完,重绘撤销按钮,更新录音按钮,
@@ -584,7 +584,7 @@ public class BFRecordScreenController: BFBaseViewController {
         //        playView = GPUImageView(frame: view.bounds)
         //        view.addSubview(playView!)
         fetchVideo()
-        //        view.addSubview(playBtn)
+        view.addSubview(playBtn)
         view.addSubview(bottomeView)
         view.addSubview(avatarView)
         //        view.addSubview(openCameraBtn)
@@ -864,14 +864,17 @@ public class BFRecordScreenController: BFBaseViewController {
         var deleteTemp = [(PQEditSubTitleModel, Int)]()
 
         for (index, title) in itemModels[currItemModelIndex].titleStickers.enumerated() {
-            if title.timelineIn >= voiceModel.startTime, title.timelineOut <= voiceModel.endTime {
+            if title.audioFilePath == voiceModel.wavFilePath {
                 deleteTemp.append((title, index))
             }
-            // 从原数组中删除
-            if let index = itemModels[currItemModelIndex].titleStickers.firstIndex(of: title) {
-                itemModels[currItemModelIndex].titleStickers.remove(at: index)
+        }
+        // 从原数组中删除
+        let arr = itemModels[currItemModelIndex].titleStickers.filter { model in
+            return !deleteTemp.contains { tuple in
+                tuple.0.audioFilePath == model.audioFilePath
             }
         }
+        itemModels[currItemModelIndex].titleStickers = arr
         BFLog(message: "itemModels[currItemModelIndex].titleStickers  删除后:\(itemModels[currItemModelIndex].titleStickers.count)")
 
         // 清空字幕UI
@@ -881,7 +884,7 @@ public class BFRecordScreenController: BFBaseViewController {
         return deleteTemp
     }
 
-    @objc func deleteRecorded() {
+    @objc func deleteRecordAction() {
         if !isDragingProgressSlder, isStopAtRecordRange != -1, isStopAtRecordRange < itemModels[currItemModelIndex].voiceStickers.count {
             let model = itemModels[currItemModelIndex].voiceStickers[isStopAtRecordRange]
             itemModels[currItemModelIndex].voiceStickers.remove(at: isStopAtRecordRange)
@@ -906,11 +909,13 @@ public class BFRecordScreenController: BFBaseViewController {
                 // 重绘录音进度视图
                 indirectionView?.resetAllSubViews(items: itemModels[currItemModelIndex].voiceStickers, percenWidth: progressThumV.thumbImageWidth / 2.0, totalDuration: itemModels[currItemModelIndex].materialDuraion)
             }
-            searchStopAtRecordRange()
-
+            
             var event = WithDrawModel(type: 3, timestamp: currentAssetProgress.seconds, deletedVoices: [(model, isStopAtRecordRange)])
             event.deletedTittles = deleteTitles(voiceModel: model)
             events.append(event)
+
+            searchStopAtRecordRange()
+
         }
     }
 
@@ -959,7 +964,7 @@ public class BFRecordScreenController: BFBaseViewController {
             assetPlayer?.play()
         }
         // 录制中不显示播放按钮
-        (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = true
+        playBtn.isSelected = true
     }
 
     @objc func endRecord() {
@@ -1001,12 +1006,12 @@ public class BFRecordScreenController: BFBaseViewController {
                     indirectionView?.deleteItem(index: modelIndex)
                     // 删除对应字幕
                     let deleteTitiles = deleteTitles(voiceModel: model)
-                    for title in deleteTitiles{
+                    for title in deleteTitiles {
                         itemModels[currItemModelIndex].titleStickers.removeAll { model in
                             title.0.timelineIn == model.timelineIn
                         }
-                    } 
-                    //恢复被覆盖的音频
+                    }
+                    // 恢复被覆盖的音频
                     var tuples = action.deletedVoices
                     if tuples != nil, tuples!.count > 0 {
                         tuples!.sort { tuple1, tuple2 in
@@ -1016,7 +1021,7 @@ public class BFRecordScreenController: BFBaseViewController {
                             itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
                         }
                     }
-                    //恢复被覆盖的字幕
+                    // 恢复被覆盖的字幕
                     let titleTuples = action.deletedTittles
                     if titleTuples != nil, titleTuples!.count > 0 {
                         titleTuples?.forEach { titleTuple in
@@ -1080,7 +1085,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
             // 如果是图片需重置播放按钮
             if itemModel.mediaType == .IMAGE {
-                (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = itemModels[currItemModelIndex].voiceStickers.count <= 0
+                playBtn.isSelected = itemModels[currItemModelIndex].voiceStickers.count <= 0
             }
         }
     }
@@ -1091,6 +1096,11 @@ public class BFRecordScreenController: BFBaseViewController {
     }
 
     @objc func playVideo(btn: UIButton) {
+        if itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0 {
+            BFLog(message: "图片没有录音无法播放")
+            return
+        }
+        btn.isSelected = !btn.isSelected
         if !btn.isSelected {
             pause()
             searchStopAtRecordRange()
@@ -1347,13 +1357,12 @@ public class BFRecordScreenController: BFBaseViewController {
         }
     }
 
-    
     /// 图片素材录音的播放
     /// - Parameters:
     ///   - currentT: <#currentT description#>
     ///   - shouldPlayRecordIndex: <#shouldPlayRecordIndex description#>
     ///   - recordedAudio: <#recordedAudio description#>
-    func imageMaterialRecordPlay(at currentT: CMTime, shouldPlayRecordIndex: Int, recordedAudio: PQVoiceModel) {
+    func imageMaterialRecordPlay(at currentT: CMTime, shouldPlayRecordIndex _: Int, recordedAudio: PQVoiceModel) {
         synced(currentPlayRecordIndex) { [weak self] in
             guard let sself = self else {
                 return
@@ -1385,6 +1394,7 @@ public class BFRecordScreenController: BFBaseViewController {
             }
         }
     }
+
     func play() {
         BFLog(1, message: "开始播放 \(currentAssetProgress.seconds)")
 
@@ -1409,7 +1419,7 @@ public class BFRecordScreenController: BFBaseViewController {
             assetPlayer?.play()
         } else {
             // 处理图片音频播放
-            playRecord(time: currentAssetProgress)
+            startPlayRecord(time: currentAssetProgress)
         }
 
         deleteRecordBtn.isHidden = true
@@ -1439,7 +1449,7 @@ public class BFRecordScreenController: BFBaseViewController {
         assetPlayer?.seek(to: currentAssetProgress, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000), completionHandler: { _ in
         })
         // 暂停状态
-        (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = (itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0)
+        playBtn.isSelected = (itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0)
     }
 
     func fetchVideo() {
@@ -1464,6 +1474,8 @@ public class BFRecordScreenController: BFBaseViewController {
             }
             collectionView.reloadData()
         }
+        // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
+        playBtn.isSelected = (itemModels.first?.mediaType == .IMAGE && (itemModels.first?.voiceStickers.count ?? 0) <= 0)
     }
 
     func setCoverImage(img: UIImage) {
@@ -1514,7 +1526,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 self?.periodicTimeObserver(item: item, time: time)
                 if self?.isNormalPlaying ?? false {
                     // 播放录音
-                    self?.playRecord(time: time)
+                    self?.startPlayRecord(time: time)
                 }
             } as? NSKeyValueObservation
         }
@@ -1529,7 +1541,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 self?.endRecord()
                 cShowHUB(superView: nil, msg: "此视频已录制到头了哦")
             }
-            (self?.collectionView.cellForItem(at: IndexPath(item: self!.currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = false
+            self?.playBtn.isSelected = false
         }
     }
 
@@ -1618,8 +1630,14 @@ public class BFRecordScreenController: BFBaseViewController {
 
     func drawProgressIndication(progress: Double) {
         if indirectionView == nil {
-            indirectionView = BFIndirectionProgressView(frame: progressThumV.progessIndicateBackV.bounds, percenWidth: itemModels[currItemModelIndex].mediaType == .IMAGE ? progressThumV.thumbImageWidth / 2 : 0, totalDuration: itemModels[currItemModelIndex].materialDuraion)
-            progressThumV.progessIndicateBackV.addSubview((indirectionView)!)
+            var percenWidth: CGFloat = 0
+            if itemModels[currItemModelIndex].mediaType == .IMAGE {
+                percenWidth = progressThumV.thumbImageWidth / 2.0
+            } else {
+                percenWidth = progressThumV.progessIndicateBackV.frame.width / CGFloat(itemModels[currItemModelIndex].materialDuraion)
+            }
+            indirectionView = BFIndirectionProgressView(frame: CGRect(origin: progressThumV.progessIndicateBackV.origin, size: CGSize(width: progressThumV.progressView.contentSize.width, height: progressThumV.progessIndicateBackV.frame.height)), percenWidth: percenWidth, totalDuration: itemModels[currItemModelIndex].materialDuraion)
+            progressThumV.progressView.addSubview((indirectionView)!)
         }
         // 更新录制进度
         // 注:视频无法以录制进度驱动,因当录音开始录音时播放器还未播放,导致进度不一致
@@ -1639,9 +1657,6 @@ public class BFRecordScreenController: BFBaseViewController {
         if let vasset = recordItem.videoAsset, let cell: BFImageCoverViewCell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
             setVideoPlay(item: recordItem.playItem, imageView: cell.playView)
             setAudioPlay(item: recordItem.playItem)
-            playBtn = cell.playBtn
-//            recordItem.videoAsset
-
             let degress = degressFromVideoFile(asset: vasset)
             switch degress {
             case 90:
@@ -1749,10 +1764,18 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             events = itemModels[currItemModelIndex].events
 
             let recordItem = itemModels[currItemModelIndex]
+            // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
+            playBtn.isSelected = (recordItem.mediaType == .IMAGE && recordItem.voiceStickers.count <= 0)
             // 重绘录音区域
             progressThumV.recordItem = recordItem
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
-                self?.indirectionView?.resetAllSubViews(items: recordItem.voiceStickers, percenWidth: recordItem.mediaType == .IMAGE ? (self?.progressThumV.thumbImageWidth ?? 0) / 2.0 : 0, totalDuration: recordItem.materialDuraion)
+                var percenWidth: CGFloat = 0
+                if recordItem.mediaType == .IMAGE {
+                    percenWidth = (self?.progressThumV.thumbImageWidth ?? 0) / 2.0
+                } else {
+                    percenWidth = (self?.progressThumV.progessIndicateBackV.frame.width ?? 0) / CGFloat(recordItem.materialDuraion)
+                }
+                self?.indirectionView?.resetAllSubViews(items: recordItem.voiceStickers, percenWidth: percenWidth, totalDuration: recordItem.materialDuraion)
             }
             // 更新缩略图
             progressThumV.isHidden = false
@@ -1791,11 +1814,11 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
 public extension BFRecordScreenController {
     /// 播放录音
     /// - Parameter time: <#time description#>
-    func playRecord(time: CMTime) {
+    func startPlayRecord(time: CMTime) {
         // 播放对应的录音音频
         if itemModels[currItemModelIndex].mediaType == .IMAGE {
             if itemModels[currItemModelIndex].materialDuraion <= 0 || currentAssetProgress.seconds >= itemModels[currItemModelIndex].materialDuraion {
-                (collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell)?.playBtn.isSelected = false
+                playBtn.isSelected = true
                 return
             }
             isNormalPlaying = true
@@ -1822,13 +1845,13 @@ public extension BFRecordScreenController {
                 } else {
                     // 注:矫正进度--一段录音播放结束后当前指针应该到当前录音结束点
                     self?.currentAssetProgress = CMTime(seconds: self?.itemModels[self?.currItemModelIndex ?? 0].voiceStickers[(recordInfo?.0 ?? 0) + 1].startTime ?? 0, preferredTimescale: 1000)
-                    self?.playRecord(time: self?.currentAssetProgress ?? CMTime.zero)
+                    self?.startPlayRecord(time: self?.currentAssetProgress ?? CMTime.zero)
                 }
             }
         }) { [weak self] _, _ in
             if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE {
                 DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
-                    self?.playRecord(time: self?.currentAssetProgress ?? CMTime.zero)
+                    self?.startPlayRecord(time: self?.currentAssetProgress ?? CMTime.zero)
                 }
             }
         }

+ 0 - 15
BFRecordScreenKit/Classes/RecordScreen/View/BFImageCoverViewCell.swift

@@ -13,15 +13,6 @@ import UIKit
 open class BFImageCoverViewCell: UICollectionViewCell {
     var btnClickHandle: ((_ sender: UIButton, _ recordItem: BFRecordItemModel?) -> Void)?
 
-    public lazy var playBtn: UIButton = {
-        let btn = UIButton(type: .custom)
-        btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
-        let vv = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
-        btn.setImage(vv.graphicsGetImage(), for: .selected)
-        btn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
-        return btn
-    }()
-
     lazy var playView: GPUImageView = {
         let playView = GPUImageView(frame: bounds)
         return playView
@@ -46,13 +37,11 @@ open class BFImageCoverViewCell: UICollectionViewCell {
         super.prepareForReuse()
         filter.removeTarget(playView)
         picture.removeTarget(filter)
-        playBtn.isSelected = false
     }
 
     override public init(frame: CGRect) {
         super.init(frame: frame)
         contentView.addSubview(playView)
-        contentView.addSubview(playBtn)
     }
 
     public required init?(coder _: NSCoder) {
@@ -76,14 +65,10 @@ open class BFImageCoverViewCell: UICollectionViewCell {
         picture.addTarget(filter)
         filter.addTarget(playView)
         picture.processImage()
-        // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
-        playBtn.isSelected = (recordItem?.mediaType == .IMAGE && (recordItem?.voiceStickers.count ?? 0) <= 0)
     }
 
     public func addLayout() {
         playView.frame = contentView.bounds
-        playBtn.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei * 2)
-        playBtn.center = contentView.center
     }
 
     @objc func btnClick(sender: UIButton) {

+ 2 - 5
BFRecordScreenKit/Classes/RecordScreen/View/BFIndirectionProgressView.swift

@@ -52,12 +52,9 @@ class BFIndirectionProgressView: UIView {
     /// - Parameter items: <#items description#>
     ///  - Parameter  percenWidth: 图片为固定值要传入,视频的话可以计算,也可以传入
     func resetAllSubViews(items: [PQVoiceModel]?, percenWidth: CGFloat = 0, totalDuration: Float64) {
-        frame.size.width = superview?.bounds.width ?? 0
+        frame.size.width = (superview as? UIScrollView)?.contentSize.width ?? 0
         self.totalDuration = totalDuration
         self.percenWidth = percenWidth
-        if self.percenWidth <= 0, totalDuration > 0 {
-            self.percenWidth = frame.width / totalDuration
-        }
         subviews.forEach { vv in
             vv.removeFromSuperview()
         }
@@ -75,7 +72,7 @@ class BFIndirectionProgressView: UIView {
     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
+            frame.size.width = (superview as? UIScrollView)?.contentSize.width ?? 0
         }
         detectionAndCreateItem(start: start, progress: progress)
         currentItem?.frame.size.width = progress < 0 ? 0 : progress * percenWidth