Selaa lähdekoodia

增加摄像头功能

harry 3 vuotta sitten
vanhempi
commit
ae3a229598

+ 3 - 3
BFRecordScreenKit/Classes/BFRecordExport.swift

@@ -78,7 +78,7 @@ public class BFRecordExport {
                     }
                 }
 
-                if itemModel.mediaType == .IMAGE {
+                if itemModel.mediaType == .Image {
                     // 图片素材
                     if !synthesisAll, itemModel.voiceStickers.count == 0 {
                         // 图片无录音在保留模式里不合成
@@ -318,13 +318,13 @@ public class BFRecordExport {
 
         guard let totalDuration = data?.reduce(0.0, { partialResult, itemModell in
             var modelDuraion = 0.0
-            if itemModell.mediaType == .IMAGE {
+            if itemModell.mediaType == .Image {
                 if itemModell.voiceStickers.count == 0, synthesisAll {
                     modelDuraion += 2
                 } else {
                     modelDuraion = itemModell.materialDuraion.seconds
                 }
-            } else if itemModell.mediaType == .VIDEO {
+            } else if itemModell.mediaType == .Video {
                 modelDuraion = itemModell.dealedDurationRanges.reduce(0.0) { partialResult, srange in
 //                    partialResult + (!synthesisAll && srange.isRecord) ?
                     if synthesisAll {

+ 10 - 4
BFRecordScreenKit/Classes/BFRecordItemModel.swift

@@ -16,6 +16,12 @@ struct SplitRecordRange {
     var index: Int
 }
 
+public enum ModelType : Int {
+    case Image
+    case Video
+    case Camera
+}
+
 public class BFRecordItemModel: NSObject {
 //    var baseMaterial : AVURLAsset?
     var localPath: String?
@@ -36,7 +42,7 @@ public class BFRecordItemModel: NSObject {
     public var thumbImgs = [UIImage]() // 缩略图集合
     public var playItem: AVPlayerItem? // 视频playerItem
     public var videoAsset: AVURLAsset? // 视频Asset
-    public var mediaType: StickerType? // 素材类型
+    public var mediaType: ModelType? // 素材类型
     public var progress: Double = 0 // 更新进度
     public var index = 0 // 素材index
     public var width = 0 // 素材宽
@@ -51,10 +57,10 @@ public class BFRecordItemModel: NSObject {
         fetchAVUrlAsset(phasset)
 
         if phasset.mediaType == .image {
-            mediaType = .IMAGE
+            mediaType = .Image
             localPath = "image"
         } else if phasset.mediaType == .video {
-            mediaType = .VIDEO
+            mediaType = .Video
             fetchPlayItem(phasset)
         }
     }
@@ -71,7 +77,7 @@ public class BFRecordItemModel: NSObject {
             // 设置首帧/封面
             if image != nil {
                 self?.coverImg = image
-                if self?.mediaType == .IMAGE {
+                if self?.mediaType == .Image {
                     if let thumImage = image?.nx_scaleToSize(size: CGSize(width: 112, height: 200)) {
                         self?.thumbImgs.append(thumImage)
                     }

+ 24 - 0
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenBaseManager.swift

@@ -0,0 +1,24 @@
+//
+//  BFRecordScreenBaseManager.swift
+//  BFRecordScreenKit
+//
+//  Created by 胡志强 on 2022/1/13.
+//
+
+import Foundation
+import GPUImage
+
+
+class BFRecordScreenBaseManager {
+    var recordItem : BFRecordItemModel?
+    var playView : GPUImageView?
+    var filter = GPUImageFilter()
+    
+    func resetEnv(){
+        
+    }
+    
+    func startRecord(){
+        
+    }
+}

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

@@ -0,0 +1,27 @@
+//
+//  BFRecordScreenCameraManager.swift
+//  BFRecordScreenKit
+//
+//  Created by 胡志强 on 2022/1/13.
+//
+
+import Foundation
+import GPUImage
+
+
+class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
+
+    let camera = GPUImageVideoCamera()
+    
+    override func resetEnv(){
+        if let pv = playView{
+            camera.startCapture()
+            camera.addTarget(filter)
+            filter.addTarget(pv)
+        }
+    }
+    
+    override func startRecord(){
+        
+    }
+}

+ 147 - 77
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -36,10 +36,59 @@ public class BFRecordScreenController: BFBaseViewController {
     public var subTitleBtnClickHandle: ((_ isOn: Bool) -> Void)?
 //    public var currentRecordId: String? // 当前录制Id
 
+    // MARK: - 素材参数
+    var rsvmanager = BFRecordScreenVideoManager()
+    var rsimanager = BFRecordScreenImageManager()
+    var rscmanager = BFRecordScreenCameraManager()
+    var rscurrentManager = BFRecordScreenBaseManager()
+    
     // MARK: - 录制参数
-
     public var assets = [PHAsset]()
-    var currItemModelIndex = 0
+    var currItemModelIndex = -1 {
+        didSet{
+            if currItemModelIndex < 0 {
+                return
+            }
+            let itemModel = itemModels[currItemModelIndex]
+            rscurrentManager.recordItem = itemModel
+            
+            switch itemModel.mediaType {
+            case .Image:
+                rscurrentManager = rsimanager
+                recordBtn.setTitle("按住 录制", for: .normal)
+                progressThumV.isHidden = true
+                
+            case .Video:
+                rscurrentManager = rsvmanager
+                recordBtn.setTitle("按住 录音", for: .normal)
+                progressThumV.isHidden = false
+
+            case .Camera:
+                rscurrentManager = rscmanager
+                recordBtn.setTitle("按住 录音", for: .normal)
+                progressThumV.isHidden = false
+            
+            default:
+                break
+            }
+            
+            if let cell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFCameraCoverViewCell {
+                cell.playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
+                rscurrentManager.playView = cell.playView
+                rscurrentManager.resetEnv()
+            }else if let cell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFVideoCoverViewCell {
+                cell.playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
+                rscurrentManager.playView = cell.playView
+                progressThumV.isHidden = false
+                rscurrentManager.resetEnv()
+            }else if let cell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
+                cell.playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
+                rscurrentManager.playView = cell.playView
+                progressThumV.isHidden = false
+                rscurrentManager.resetEnv()
+            }
+        }
+    }
     public var itemModels = [BFRecordItemModel]()
     // add by ak 当前的显示的字幕位置
     var showSubtitleIndex = -1
@@ -53,7 +102,7 @@ public class BFRecordScreenController: BFBaseViewController {
             subtitleBtn.isHidden = isRecording
             soundSettingBtn.isHidden = isRecording
 
-            recordBtn.setTitle(isRecording ? "松手 暂停" : "按住 录音", for: .normal)
+            recordBtn.setTitle(isRecording ? "松手 暂停" : (rscurrentManager.recordItem?.mediaType == .Camera ? "按住 录制" : "按住 录音"), for: .normal)
             recordBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#389AFF", alpha: isRecording ? 0.6 : 1)
 //            if !isRecording {
 //                BFLog(1, message: "stop")
@@ -159,15 +208,6 @@ public class BFRecordScreenController: BFBaseViewController {
         btn.center = view.center
         return btn
     }()
-    
-    @objc func playbtnDown(btn:UIButton){
-        let vv = UIView(frame: CGRect(x: 0, y: 0, width: 0.5, height: 0.5))
-        vv.backgroundColor = UIColor.init(white: 1, alpha: 0.3)
-        btn.setImage(vv.graphicsGetImage(), for: .normal)
-    }
-    @objc func playbtnCancle(btn:UIButton){
-        btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
-    }
 
     lazy var bottomeView: UIImageView = {
         let iv = UIImageView(image: imageInRecordScreenKit(by: "bottom_shadow"))
@@ -383,6 +423,7 @@ public class BFRecordScreenController: BFBaseViewController {
         let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), collectionViewLayout: flowLayout)
         collectionView.register(BFImageCoverViewCell.self, forCellWithReuseIdentifier: String(describing: BFImageCoverViewCell.self))
         collectionView.register(BFVideoCoverViewCell.self, forCellWithReuseIdentifier: String(describing: BFVideoCoverViewCell.self))
+        collectionView.register(BFCameraCoverViewCell.self, forCellWithReuseIdentifier: String(describing: BFCameraCoverViewCell.self))
         collectionView.isPagingEnabled = true
         collectionView.bounces = false
         collectionView.showsVerticalScrollIndicator = false
@@ -458,6 +499,13 @@ public class BFRecordScreenController: BFBaseViewController {
         navigationController?.isNavigationBarHidden = true
         hiddenNavigation()
     }
+    
+    public override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        endScrollItem(collectionView)
+        // 设置默认值
+        setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
+    }
 
     override public func viewWillDisappear(_ animated: Bool) {
         super.viewWillDisappear(animated)
@@ -503,12 +551,7 @@ public class BFRecordScreenController: BFBaseViewController {
             DispatchQueue.global().async { [weak self] in
                 let newSubtitle = PQEditSubTitleModel()
                 newSubtitle.recordId = recordId
-//                    if eventCode == 26 {
-//                        self?.currentRecordId = nil
-//                    }
-//                    if eventCode == 0 {
-//                        self?.currentRecordId = recordId
-//                    }
+
                 if asrResult == nil || (asrResult?.count ?? 0) <= 0 {
                     BFLog(1, message: "onNuiEventCallback 识别结果为空????不能生成字幕数据")
                     return
@@ -573,7 +616,6 @@ public class BFRecordScreenController: BFBaseViewController {
         }
 
         // MARK: -  录音结束
-
         recorderManager?.endRecordHandle = { [weak self, weak recorderManager] voideModel, _ in
             if let sself = self, let model = voideModel, FileManager.default.fileExists(atPath: model.wavFilePath ?? "") {
                 // 加入到语音数组里
@@ -615,7 +657,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 self?.recordEndHandle?(model)
                 // 如果是图片素材同时有需要删除的录音时需要调整录音文件开始结束时间
                 // warning: 图片录制的时候应该只能在结尾处录制
-                if sself.itemModels[sself.currItemModelIndex].mediaType == .IMAGE {
+                if sself.itemModels[sself.currItemModelIndex].mediaType == .Image {
                     if deletedVoices.count > 0 {
                         // 如果是图片先排序在计算区间
                         sself.itemModels[sself.currItemModelIndex].voiceStickers = sself.itemModels[sself.currItemModelIndex].voiceStickers.sorted { voice1, voice2 in
@@ -640,7 +682,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 event.deletedTittles = deletedTitlesTemp
                 sself.events.append(event)
 
-                if sself.itemModels[sself.currItemModelIndex].mediaType == .IMAGE {
+                if sself.itemModels[sself.currItemModelIndex].mediaType == .Image {
                     var duration: CMTime = .zero
                     sself.itemModels[sself.currItemModelIndex].voiceStickers.forEach { temp in
                         BFLog(1, message: "录制结束-最终:\(temp.wavFilePath ?? "")-\(temp.startCMTime.seconds)-\(temp.endCMTime.seconds)-\(temp.endCMTime.seconds - temp.startCMTime.seconds)")
@@ -665,7 +707,7 @@ public class BFRecordScreenController: BFBaseViewController {
                     // 矫正进度
                     self?.resetCurrentProgress()
                     self?.deleteRecordBtn.isHidden = true
-                    self?.recordBtn.isHidden = (self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE && (self?.isEndPlay ?? false)) ? false : (self?.isEndPlay ?? false)
+                    self?.recordBtn.isHidden = (self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .Image && (self?.isEndPlay ?? false)) ? false : (self?.isEndPlay ?? false)
                 }
                 sself.currentPlayRecordIndex = -3 // 刚录音完,不需要播放录音
                 BFLog(3, message: "重置播放index-\(#function) = \(sself.currentPlayRecordIndex)")
@@ -696,15 +738,15 @@ public class BFRecordScreenController: BFBaseViewController {
 
         view.backgroundColor = .black
         view.addSubview(collectionView)
-        //        playView = GPUImageView(frame: view.bounds)
-        //        view.addSubview(playView!)
+        
         fetchVideo()
+        
         view.addSubview(bottomeView)
 //        view.addSubview(subtitleLabel)
         view.addSubview(playBtn)
         view.addSubview(avatarView)
-        //        view.addSubview(openCameraBtn)
-        //        view.addSubview(drawPinBtn)
+//        view.addSubview(openCameraBtn)
+//        view.addSubview(drawPinBtn)
         view.addSubview(subtitleBtn)
         view.addSubview(soundSettingBtn)
         view.addSubview(subtitleSettingView)
@@ -723,8 +765,7 @@ public class BFRecordScreenController: BFBaseViewController {
             BFLog(message: "新录制完成::::\(materialsModel?.locationPath ?? "")")
         }
 
-        // 设置默认值
-        setSubtitleStyle(settingModel: subtitleSettingView.subtitle.setting)
+
         // 字幕设置回调
         subtitleSettingView.subtitleSettingCallBack = { [weak self] subtitileModel in
 
@@ -1035,7 +1076,7 @@ public class BFRecordScreenController: BFBaseViewController {
             events.append(event)
 
             // 注:删除录音后图片素材需要回撤指针进度,同时后面录音往前挪
-            if itemModels[currItemModelIndex].mediaType == .IMAGE {
+            if itemModels[currItemModelIndex].mediaType == .Image {
                 let currDuration = model.endCMTime - model.startCMTime
                 itemModels[currItemModelIndex].materialDuraion = itemModels[currItemModelIndex].materialDuraion - currDuration
                 currentAssetProgress = model.startCMTime
@@ -1116,7 +1157,7 @@ public class BFRecordScreenController: BFBaseViewController {
         if !avatarView.isHidden {
             avatarView.beginRecord()
         }
-        if itemModels[currItemModelIndex].mediaType == .VIDEO {
+        if itemModels[currItemModelIndex].mediaType == .Video {
             if !movieIsProcessing {
                 movie?.startProcessing()
                 movieIsProcessing = true
@@ -1209,7 +1250,7 @@ public class BFRecordScreenController: BFBaseViewController {
         BFLog(2, message: "删除\(voiceModel?.wavFilePath ?? "")对应的字幕  后 count\(subtitleCount)")
         /// 重置进度
         if voiceModel?.currIndex == currItemModelIndex {
-            if itemModels[currItemModelIndex].mediaType == .IMAGE {
+            if itemModels[currItemModelIndex].mediaType == .Image {
                 currentAssetProgress = CMTime(seconds: recorderManager?.voiceModel?.startCMTime.seconds ?? 0, preferredTimescale: 1000)
                 if currentAssetProgress.seconds >= itemModels[currItemModelIndex].materialDuraion.seconds {
                     currentAssetProgress = CMTime(seconds: itemModels[currItemModelIndex].materialDuraion.seconds, preferredTimescale: 1000)
@@ -1261,7 +1302,7 @@ public class BFRecordScreenController: BFBaseViewController {
                     }
 //                    jumpTime = model.startCMTime.seconds
 
-                    if itemModels[currItemModelIndex].mediaType == .IMAGE {
+                    if itemModels[currItemModelIndex].mediaType == .Image {
                         itemModels[currItemModelIndex].materialDuraion = model.startCMTime
                     }
                 }
@@ -1271,7 +1312,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 tuples?.sort { tuple1, tuple2 in
                     tuple1.1 < tuple2.1
                 }
-                if itemModels[currItemModelIndex].mediaType == .VIDEO {
+                if itemModels[currItemModelIndex].mediaType == .Video {
                     tuples?.forEach { tuple in
                         itemModels[currItemModelIndex].voiceStickers.insert(tuple.0, at: tuple.1)
                     }
@@ -1305,7 +1346,7 @@ public class BFRecordScreenController: BFBaseViewController {
                         itemModels[currItemModelIndex].titleStickers.append(titleTuple)
                     }
                 }
-                if itemModels[currItemModelIndex].mediaType == .IMAGE {
+                if itemModels[currItemModelIndex].mediaType == .Image {
                     itemModels[currItemModelIndex].materialDuraion = itemModels[currItemModelIndex].voiceStickers.last?.endCMTime ?? .zero
                 }
 
@@ -1314,7 +1355,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
             let dur = itemModels[currItemModelIndex].materialDuraion.seconds
             if dur > 0 {
-                if itemModels[currItemModelIndex].mediaType == .IMAGE {
+                if itemModels[currItemModelIndex].mediaType == .Image {
                     changeProgress(isBack: true, progress: Float(jumpTime.seconds))
                 } else {
                     changeProgress(changCMTime: jumpTime)
@@ -1339,7 +1380,7 @@ public class BFRecordScreenController: BFBaseViewController {
             /// 重绘录音进度视图
             resetAllIndirectionView()
             // 如果是图片需重置播放按钮
-            if itemModel.mediaType == .IMAGE {
+            if itemModel.mediaType == .Image {
                 playBtn.isSelected = itemModels[currItemModelIndex].voiceStickers.count <= 0
                 playBtn.isHidden = playBtn.isSelected
             }
@@ -1350,11 +1391,20 @@ public class BFRecordScreenController: BFBaseViewController {
         //        nextActionHandle?()
         pause()
     }
+    
+    @objc func playbtnDown(btn:UIButton){
+        let vv = UIView(frame: CGRect(x: 0, y: 0, width: 0.5, height: 0.5))
+        vv.backgroundColor = UIColor.init(white: 1, alpha: 0.3)
+        btn.setImage(vv.graphicsGetImage(), for: .normal)
+    }
+    @objc func playbtnCancle(btn:UIButton){
+        btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
+    }
 
     @objc func playVideo(btn: UIButton) {
         btn.setImage(imageInRecordScreenKit(by: "preview_play"), for: .normal)
 
-        if itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0 {
+        if itemModels[currItemModelIndex].mediaType == .Image && itemModels[currItemModelIndex].voiceStickers.count <= 0 {
             BFLog(message: "图片没有录音无法播放")
             btn.isSelected = true
             return
@@ -1401,7 +1451,7 @@ public class BFRecordScreenController: BFBaseViewController {
         
         if CMTimeCompare(currentAssetProgress, itemModels[currItemModelIndex].materialDuraion) >= 0  {
             // 视频拖动到最后隐藏录制按钮
-            if itemModels[currItemModelIndex].mediaType == .VIDEO  {
+            if itemModels[currItemModelIndex].mediaType == .Video  {
                 recordBtn.isHidden = true
             } else {
                 recordBtn.isHidden = false
@@ -1614,7 +1664,7 @@ public class BFRecordScreenController: BFBaseViewController {
 //                }
             } as? NSKeyValueObservation
         }
-        if itemModels[currItemModelIndex].mediaType == .VIDEO {
+        if itemModels[currItemModelIndex].mediaType == .Video {
             videoMaterialRecordPlay(at: currentT, shouldPlayRecordIndex: shouldPlayRecordIndex, recordedAudio: recordedAudio)
         } else {
             imageMaterialRecordPlay(at: currentT, shouldPlayRecordIndex: shouldPlayRecordIndex, recordedAudio: recordedAudio)
@@ -1643,7 +1693,7 @@ public class BFRecordScreenController: BFBaseViewController {
                CMTimeGetSeconds(currentT) >= (recordedAudio.startCMTime.seconds - 0.1),
                CMTimeGetSeconds(currentT) <= recordedAudio.endCMTime.seconds - 0.2 // 这个条件是避免录音结束后有小幅度回退导致播放最新录音
             {
-                if itemModels[currItemModelIndex].mediaType == .VIDEO, recordPlayer?.currentItem?.duration.timescale == 0 {
+                if itemModels[currItemModelIndex].mediaType == .Video, recordPlayer?.currentItem?.duration.timescale == 0 {
                     return
                 }
                 // 应当开始播放了
@@ -1706,18 +1756,18 @@ public class BFRecordScreenController: BFBaseViewController {
         }
 
         isNormalPlaying = true
-        if isEndPlay || (itemModels[currItemModelIndex].mediaType == .IMAGE && CMTimeCompare(currentAssetProgress, itemModels[currItemModelIndex].materialDuraion) >= 0) {
+        if isEndPlay || (itemModels[currItemModelIndex].mediaType == .Image && CMTimeCompare(currentAssetProgress, itemModels[currItemModelIndex].materialDuraion) >= 0) {
             isEndPlay = false
             assetPlayer?.seek(to: CMTime.zero)
             progressThumV.progress = 0
             currentPlayRecordIndex = -1
             BFLog(3, message: "重置播放index-\(#function) = \(currentPlayRecordIndex)")
-            if itemModels[currItemModelIndex].mediaType == .VIDEO {
+            if itemModels[currItemModelIndex].mediaType == .Video {
                 recordBtn.isHidden = false
             }
             currentAssetProgress = CMTime.zero
         }
-        if itemModels[currItemModelIndex].mediaType == .VIDEO {
+        if itemModels[currItemModelIndex].mediaType == .Video {
             if !movieIsProcessing {
                 movie?.startProcessing()
                 movieIsProcessing = true
@@ -1752,7 +1802,7 @@ public class BFRecordScreenController: BFBaseViewController {
         subtitleBtn.isHidden = false
         soundSettingBtn.isHidden = false
         withDrawBtn.isHidden = false
-        recordBtn.isHidden = (itemModels[currItemModelIndex].mediaType == .IMAGE && isEndPlay) ? false : isEndPlay
+        recordBtn.isHidden = (itemModels[currItemModelIndex].mediaType == .Image && isEndPlay) ? false : isEndPlay
 
         assetPlayer?.pause()
         recordPlayer?.pause()
@@ -1762,13 +1812,12 @@ public class BFRecordScreenController: BFBaseViewController {
         hadPrepareToPlayRecord = false
 
         // 暂停状态
-        playBtn.isSelected = (itemModels[currItemModelIndex].mediaType == .IMAGE && itemModels[currItemModelIndex].voiceStickers.count <= 0)
+        playBtn.isSelected = (itemModels[currItemModelIndex].mediaType == .Image && itemModels[currItemModelIndex].voiceStickers.count <= 0)
         playBtn.isHidden = playBtn.isSelected
     }
 
     func fetchVideo() {
         if assets.count > 0 {
-            currItemModelIndex = 0
             for (index, asset) in assets.enumerated() {
                 let itemModel = BFRecordItemModel()
                 itemModel.index = index
@@ -1784,7 +1833,7 @@ public class BFRecordScreenController: BFBaseViewController {
                                 self?.progressThumV.recordItem = itemModel
                                 self?.progressThumV.isHidden = false
                                 self?.recordBtn.isEnabled = true
-                                self?.reloadMaterial()
+//                                self?.reloadVideoMaterial()
                             }
                         }
                     } else {
@@ -1792,10 +1841,18 @@ public class BFRecordScreenController: BFBaseViewController {
                     }
                 }
             }
-            collectionView.reloadData()
+        }else {
+            let itemModel = BFRecordItemModel()
+            itemModel.index = 0
+            itemModel.mediaType = .Camera
+            itemModels.append(itemModel)
+            
+            recordBtn.isEnabled = true
         }
+        collectionView.reloadData()
+
         // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
-        playBtn.isSelected = (itemModels.first?.mediaType == .IMAGE && (itemModels.first?.voiceStickers.count ?? 0) <= 0)
+        playBtn.isSelected = (itemModels.first?.mediaType == .Image && (itemModels.first?.voiceStickers.count ?? 0) <= 0)
         playBtn.isHidden = playBtn.isSelected
     }
 
@@ -1866,7 +1923,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
             sself.isNormalPlaying = false
             sself.isEndPlay = true
-            sself.recordBtn.isHidden = (sself.itemModels[sself.currItemModelIndex].mediaType == .IMAGE) ? false : true
+            sself.recordBtn.isHidden = (sself.itemModels[sself.currItemModelIndex].mediaType == .Image) ? false : true
 
             sself.subtitleBtn.isHidden = false
             sself.soundSettingBtn.isHidden = false
@@ -1887,7 +1944,7 @@ public class BFRecordScreenController: BFBaseViewController {
         //        if time.seconds < pauseTime {
         //            return
         //        }
-        if itemModels[currItemModelIndex].mediaType == .VIDEO {
+        if itemModels[currItemModelIndex].mediaType == .Video {
             if CMTimeGetSeconds(item?.duration ?? CMTime.zero) > 0 {
                 currentAssetProgress = CMTime(seconds: time.seconds, preferredTimescale: 1000)
 //                BFLog(1, message: "video curr:\(CMTimeGetSeconds(currentAssetProgress))")
@@ -1955,7 +2012,7 @@ public class BFRecordScreenController: BFBaseViewController {
         if progress.isNaN || progress.isInfinite {
             newProgress = 0
         }
-        if itemModels[currItemModelIndex].mediaType == .VIDEO {
+        if itemModels[currItemModelIndex].mediaType == .Video {
             let duration = itemModels[currItemModelIndex].materialDuraion
             if duration.seconds > 0 {
                 if progress == -1 {
@@ -1990,7 +2047,7 @@ public class BFRecordScreenController: BFBaseViewController {
     func drawProgressIndication(progress: Double) {
         if indirectionView == nil {
             var percenWidth: CGFloat = 0
-            if itemModels[currItemModelIndex].mediaType == .IMAGE {
+            if itemModels[currItemModelIndex].mediaType == .Image {
                 percenWidth = progressThumV.thumbImageWidth / 2.0
             } else {
                 percenWidth = progressThumV.progessIndicateBackV.frame.width / CGFloat(itemModels[currItemModelIndex].materialDuraion.seconds)
@@ -2001,24 +2058,24 @@ public class BFRecordScreenController: BFBaseViewController {
         // 更新录制进度
         // 注:视频无法以录制进度驱动,因当录音开始录音时播放器还未播放,导致进度不一致
         // 注:在录制停止时,视频播放器进度依然在走,误差在80毫秒左右
-        if isRecording, itemModels[currItemModelIndex].mediaType == .IMAGE {
+        if isRecording, itemModels[currItemModelIndex].mediaType == .Image {
             let startTime = recorderManager?.voiceModel?.startCMTime.seconds ?? 0
             // 使用播放器的进度来画线,因为进度是跟着播放器来了
             indirectionView?.setProgress(start: startTime, progress: progress)
         }
-        if itemModels[currItemModelIndex].mediaType == .IMAGE {
+        if itemModels[currItemModelIndex].mediaType == .Image {
             imageRecordProgress(isRecord: true, progress: progress)
         }
     }
 
     // 修正视频旋转方向,因为自己录制的竖屏视频会预览为横屏
-    func reloadMaterial() {
+    func reloadVideoMaterial() {
         let recordItem = itemModels[currItemModelIndex]
         BFLog(message: "设置播放器reloadMaterial:\(recordItem)")
-        if let vasset = recordItem.videoAsset, let cell: BFImageCoverViewCell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
+        if let vasset = recordItem.videoAsset, let playItem = recordItem.playItem, let cell: BFImageCoverViewCell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell {
             BFLog(message: "设置播放器reloadMaterial-开始:\(recordItem)")
-            setVideoPlay(item: recordItem.playItem, imageView: cell.playView)
-            setAudioPlay(item: recordItem.playItem)
+            setVideoPlay(item: playItem, imageView: cell.playView)
+            setAudioPlay(item: playItem)
             let degress = degressFromVideoFile(asset: vasset)
             switch degress {
             case 90:
@@ -2065,17 +2122,31 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
     public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
         let recordItem = itemModels[indexPath.item]
         var cell: BFImageCoverViewCell!
-        if recordItem.mediaType == .VIDEO {
-            cell = BFVideoCoverViewCell.gpuVideoViewCell(collectionView: collectionView, indexPath: indexPath)
-        } else {
+
+        switch recordItem.mediaType {
+        case .Image:
             cell = BFImageCoverViewCell.gpuImageViewCell(collectionView: collectionView, indexPath: indexPath)
+        case .Video:
+            cell = BFVideoCoverViewCell.gpuVideoViewCell(collectionView: collectionView, indexPath: indexPath)
+        case .Camera:
+            cell = BFCameraCoverViewCell.gpuCamraViewCell(collectionView: collectionView, indexPath: indexPath)
+            (cell as! BFCameraCoverViewCell).initCameraAfterData = {[weak self] in
+//                if self?.currItemModelIndex == indexPath.row {
+//                    // 开启摄像头
+//                    self?.rscurrentManager.playView = cell.playView
+//                    self?.rscurrentManager.resetEnv()
+//                }
+            }
+        default:
+            break
         }
+        
         recordItem.fetchCoverImgCallBack = { [weak self, weak cell, weak recordItem] _ in
             guard let sself = self, let item = recordItem else {
                 return
             }
             cell?.addData()
-            if item.mediaType == .IMAGE {
+            if item.mediaType == .Image {
                 sself.progressThumV.recordItem = item
                 sself.progressThumV.isHidden = false
             }
@@ -2088,9 +2159,9 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             guard let sself = self else {
                 return
             }
-            if indexPath.item == sself.currItemModelIndex {
-                sself.reloadMaterial()
-            }
+//            if indexPath.item == sself.currItemModelIndex {
+//                sself.reloadVideoMaterial()
+//            }
         }
         cell.btnClickHandle = { [weak self] _, _ in
             guard let sself = self else {
@@ -2126,7 +2197,7 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
         let page = Int((scrollView.contentOffset.x + scrollView.frame.width / 2) / scrollView.frame.width)
         if page != currItemModelIndex {
             // 切换素材时先把录制状态切为不可用,延迟可点,避免在缩略图未加载出来时即可录制
-            recordBtn.isEnabled = false
+            currItemModelIndex = page
             // 暂停
             pause()
             // 如果在录制中,停止录制
@@ -2140,11 +2211,10 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
 //            events = itemModels[page].events
             events = [WithDrawModel]()
 
-            currItemModelIndex = page
 
             let recordItem = itemModels[currItemModelIndex]
             // 暂停状态--如果是图片素材同时没有录音文件时不显示播放按钮
-            playBtn.isSelected = (recordItem.mediaType == .IMAGE && recordItem.voiceStickers.count <= 0)
+            playBtn.isSelected = (recordItem.mediaType == .Image && recordItem.voiceStickers.count <= 0)
             playBtn.isHidden = playBtn.isSelected
             // 重绘录音区域
             progressThumV.recordItem = recordItem
@@ -2176,8 +2246,8 @@ extension BFRecordScreenController: UICollectionViewDelegate, UICollectionViewDa
             searchStopAtRecordRange()
             changeWithDrawBtnLayout(0)
             pauseTime = 0
-            if recordItem.mediaType == .VIDEO {
-                reloadMaterial()
+            if recordItem.mediaType == .Video {
+                reloadVideoMaterial()
                 assetPlayer?.seek(to: .zero, toleranceBefore: CMTime(value: 1, timescale: 1_000_000), toleranceAfter: CMTime(value: 1, timescale: 1_000_000))
             }
             if changeItemHandle != nil {
@@ -2209,7 +2279,7 @@ public extension BFRecordScreenController {
     /// - Parameter time: <#time description#>
     func startPlayRecord(time: CMTime) {
         // 播放对应的录音音频
-        if itemModels[currItemModelIndex].mediaType == .IMAGE {
+        if itemModels[currItemModelIndex].mediaType == .Image {
             if itemModels[currItemModelIndex].materialDuraion.seconds <= 0 {
                 playBtn.isSelected = true
                 playBtn.isHidden = playBtn.isSelected
@@ -2222,12 +2292,12 @@ public extension BFRecordScreenController {
         }
         playRecord(at: time, periodicTimeObserver: { [weak self] currentT, _ in
 //            BFLog(1, message: "播放录音进度:\(currentT.seconds),\(currentItem)")
-            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE, self?.isNormalPlaying ?? false {
+            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .Image, self?.isNormalPlaying ?? false {
                 self?.imageRecordProgress(progress: CMTimeGetSeconds(currentT))
             }
         }, didPlayToEndTime: { [weak self] recordInfo, currentItem in
             BFLog(message: "播放录音结束:\(String(describing: recordInfo?.1)),\(String(describing: currentItem))")
-            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE {
+            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 {
                     
                     self?.isEndPlay = true
@@ -2245,7 +2315,7 @@ public extension BFRecordScreenController {
                 }
             }
         }) { [weak self] _, _ in
-            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .IMAGE {
+            if self?.itemModels[self?.currItemModelIndex ?? 0].mediaType == .Image {
                 DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
                     self?.startPlayRecord(time: self?.currentAssetProgress ?? CMTime.zero)
                 }
@@ -2261,7 +2331,7 @@ public extension BFRecordScreenController {
             currentAssetProgress = recordStartPlayTime + CMTime(seconds: progress, preferredTimescale: 1000)
         }
         BFLog(1, message: "图片录音进度:\(progress),currentAssetProgress=\(currentAssetProgress.seconds),\(itemModels[currItemModelIndex].materialDuraion)")
-        if itemModels[currItemModelIndex].mediaType == .IMAGE {
+        if itemModels[currItemModelIndex].mediaType == .Image {
             /// 重置进度
             resetCurrentProgress()
         }
@@ -2284,7 +2354,7 @@ public extension BFRecordScreenController {
     func resetAllIndirectionView() {
         // 重绘录音进度视图
         var percenWidth: CGFloat = 0
-        if itemModels[currItemModelIndex].mediaType == .IMAGE {
+        if itemModels[currItemModelIndex].mediaType == .Image {
             percenWidth = progressThumV.thumbImageWidth / 2.0
         } else {
             percenWidth = progressThumV.progessIndicateBackV.frame.width / CGFloat(itemModels[currItemModelIndex].materialDuraion.seconds)

+ 2 - 2
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenImageController.swift → BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenImageManager.swift

@@ -1,5 +1,5 @@
 //
-//  BFRecordScreenImageController.swift
+//  BFRecordScreenImageManager.swift
 //  BFRecordScreenKit
 //
 //  Created by 胡志强 on 2021/12/14.
@@ -7,7 +7,7 @@
 
 import Foundation
 
-class BFRecordScreenImageController: BFRecordScreenController {
+class BFRecordScreenImageManager : BFRecordScreenBaseManager{
     override func startRecord() {
         super.startRecord()
     }

+ 1 - 1
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenVideoController.swift → BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenVideoManager.swift

@@ -7,7 +7,7 @@
 
 import Foundation
 
-class BFRecordScreenVideoController: BFRecordScreenController {
+class BFRecordScreenVideoManager : BFRecordScreenBaseManager{
     override func startRecord() {
         super.startRecord()
     }

+ 2 - 2
BFRecordScreenKit/Classes/RecordScreen/View/BFRecordAvatarView.swift

@@ -85,12 +85,12 @@ class BFRecordAvatarView: UIView {
 
     // 打开摄像头
     func openCamera() {
-//        camera.startCapture()
+        camera.startCapture()
     }
 
     // 关闭摄像头
     func closeCamera() {
-//        camera.stopCapture()
+        camera.stopCapture()
     }
 
     // 开始录制

+ 12 - 12
BFRecordScreenKit/Classes/RecordScreen/View/BFVideoThumbProgressView.swift

@@ -18,9 +18,9 @@ class BFVideoThumbProgressView: UIView {
             // 指针回归
             BFLog(1, message: "new recorditem")
             progress = 0
-            if recordItem?.mediaType == .VIDEO {
+            if recordItem?.mediaType == .Video {
                 dealWithVideoThumb()
-            } else if recordItem?.mediaType == .IMAGE {
+            } else if recordItem?.mediaType == .Image {
                 dealWithImageThumb()
             }
         }
@@ -190,7 +190,7 @@ class BFVideoThumbProgressView: UIView {
                         }
                         sself.lastImg = iv
                     }
-                    if sself.recordItem?.mediaType == .IMAGE {
+                    if sself.recordItem?.mediaType == .Image {
                         // 图片需要动态修改宽度
                         sself.lastImg?.snp.makeConstraints { make in
                             make.right.equalTo(sself.width * -0.5)
@@ -206,7 +206,7 @@ class BFVideoThumbProgressView: UIView {
             guard let sslf = self else { return }
             let count: Int = Int(progress / 2)
 //            BFLog(message: "需要的图片个数:progress=\(progress),count=\(count)")
-            if sslf.recordItem?.mediaType == .IMAGE, (sslf.progressView.contentView.subviews.count - 6) < count {
+            if sslf.recordItem?.mediaType == .Image, (sslf.progressView.contentView.subviews.count - 6) < count {
                 guard let image = (sslf.recordItem?.thumbImgs.first ?? sslf.recordItem?.coverImg) else {
                     return
                 }
@@ -240,13 +240,13 @@ class BFVideoThumbProgressView: UIView {
         if progressView.contentSize.width <= 0 {
             return
         }
-        if recordItem?.mediaType == .VIDEO {
+        if recordItem?.mediaType == .Video {
             if let second = recordItem?.materialDuraion.seconds, second > 0 {
                 let w = progressView.contentSize.width - width
                 BFLog(message: "录音进度--指示器:progress=\(progress),duration=\(second),w=\(w),perW=\(Double(w) / second),totalW:\(progress * Double(w) / second)")
                 progressView.contentOffset = CGPoint(x: progress * Double(w) / second, y: 0)
             }
-        } else if recordItem?.mediaType == .IMAGE {
+        } else if recordItem?.mediaType == .Image {
 //            if (recordItem?.materialDuraion ?? 0) > progress {
             BFLog(message: "updateProgress:\(progress)")
             progressView.contentOffset = CGPoint(x: progress * thumbImageWidth / 2.0, y: 0)
@@ -258,12 +258,12 @@ class BFVideoThumbProgressView: UIView {
 
 extension BFVideoThumbProgressView: UIScrollViewDelegate {
     func scrollViewDidScroll(_ scrollView: UIScrollView) {
-        let totalW = recordItem?.mediaType == .VIDEO ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
-        if recordItem?.mediaType == .VIDEO {
+        let totalW = recordItem?.mediaType == .Video ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
+        if recordItem?.mediaType == .Video {
             if isDrag {
                 dragScrollProgressHandle?(false, totalW > 0 ? min(Float(scrollView.contentOffset.x / totalW), 1) : 0)
             }
-        } else if recordItem?.mediaType == .IMAGE {
+        } else if recordItem?.mediaType == .Image {
             if isDrag {
                 if scrollView.contentOffset.x > ((CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0) + 0.5) {
                     scrollView.contentOffset = CGPoint(x: (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0) + 0.5, y: 0)
@@ -275,21 +275,21 @@ extension BFVideoThumbProgressView: UIScrollViewDelegate {
 
     func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
         isDrag = true
-        let totalW = recordItem?.mediaType == .VIDEO ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
+        let totalW = recordItem?.mediaType == .Video ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
         dragStartHandle?()
         dragScrollProgressHandle?(true, totalW > 0 ? min(Float(scrollView.contentOffset.x / totalW), 1) : 0)
     }
 
     func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
         if !decelerate {
-            let totalW = recordItem?.mediaType == .VIDEO ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
+            let totalW = recordItem?.mediaType == .Video ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
             isDrag = false
             dragEndHandle?(totalW > 0 ? min(Float(scrollView.contentOffset.x / totalW), 1) : 0)
         }
     }
 
     func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        let totalW = recordItem?.mediaType == .VIDEO ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
+        let totalW = recordItem?.mediaType == .Video ? (scrollView.contentSize.width - width) : (CGFloat(recordItem?.materialDuraion.seconds ?? 0) * thumbImageWidth / 2.0)
         isDrag = false
         dragEndHandle?(totalW > 0 ? min(Float(scrollView.contentOffset.x / totalW), 1) : 0)
     }

+ 26 - 0
BFRecordScreenKit/Classes/RecordScreen/View/Cell/BFCameraCoverViewCell.swift

@@ -0,0 +1,26 @@
+//
+//  BFCameraCoverViewCell.swift
+//  BFRecordScreenKit
+//
+//  Created by 胡志强 on 2022/1/14.
+//
+
+import Foundation
+
+open class BFCameraCoverViewCell: BFImageCoverViewCell {
+    
+    public var initCameraAfterData:(()->())?
+    
+    @objc public class func gpuCamraViewCell(collectionView: UICollectionView, indexPath: IndexPath) -> BFCameraCoverViewCell {
+        let cell: BFCameraCoverViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: BFCameraCoverViewCell.self), for: indexPath) as! BFCameraCoverViewCell
+        return cell
+    }
+    
+    public override var recordItem: BFRecordItemModel? {
+        didSet {
+//            addData()
+            addLayout()
+            initCameraAfterData?()
+        }
+    }
+}

+ 0 - 0
BFRecordScreenKit/Classes/RecordScreen/View/BFImageCoverViewCell.swift → BFRecordScreenKit/Classes/RecordScreen/View/Cell/BFImageCoverViewCell.swift


+ 0 - 0
BFRecordScreenKit/Classes/RecordScreen/View/BFVideoCoverViewCell.swift → BFRecordScreenKit/Classes/RecordScreen/View/Cell/BFVideoCoverViewCell.swift