Jelajahi Sumber

镜头反转

胡志强 3 tahun lalu
induk
melakukan
fd6fe2dc25

+ 14 - 5
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenCameraManager.swift

@@ -36,6 +36,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
     
     // 录制完成回调
     var hasInitCallBack : (()->Void)?
+    var cameraFlipHandle : ((Bool) -> Void)?
     var recordEndCallBack : recordEndCallBack?
     var recordProgressCallBack : ((CMTime) -> Void)?
     
@@ -49,7 +50,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
     fileprivate var timerr:Timer?
     
     var writerlock = false
-    
+    var isFrontCamera = false
     // 录制时音频结果
     var recordFinishedResult = false
     var hadDeleteVideoOfFailed = false
@@ -177,9 +178,17 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         }
     }
     
+    func cameraFlip(){
+//        [self.camera rotateCamera];
+        isFrontCamera = !isFrontCamera
+        cameraFlipHandle?(isFrontCamera)
+        camera?.horizontallyMirrorFrontFacingCamera = isFrontCamera
+        camera?.rotateCamera()
+    }
+    
     override func startRecord(){
         
-        gropQueue.enter() // 录音
+        gropQueue.enter() // 录音回调等待
         groupCount += 1
 
         guard let movieWrite = movieWrite, !writerlock else {
@@ -222,7 +231,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
                 wself.videoModel.timelineCMOut = currDur
                 wself.recordProgressCallBack?(currDur)
                 wself.updateUI(progress: currDur)
-//                BFLog(1, message: "currTime: \(wself.currentAssetProgress.seconds)")
+//                BFLog(1, message: "frame: \(wself.currentAssetProgress.seconds)")
             }
             
 //            wself.getThumImage()
@@ -616,7 +625,7 @@ class BFRecordScreenCameraManager : BFRecordScreenBaseManager{
         }
     }
     
-    // 初始化 movieWrite
+    // 每次录制完一段视频,都要重新初始化 movieWrite
     func initerlizeWriter(){
         if FileManager.default.fileExists(atPath: vpath){
             try? FileManager.default.removeItem(atPath: vpath)
@@ -660,7 +669,7 @@ extension BFRecordScreenCameraManager : GPUImageVideoCameraDelegate {
             let ciImage = CIImage(cvPixelBuffer: buffer)
             let img = UIImage(ciImage: ciImage.oriented(forExifOrientation: 6),
                               scale: cScreenWidth / 70.0,
-                              orientation: .up)
+                              orientation: isFrontCamera ? .upMirrored : .up)
             if let data = img.jpegData(compressionQuality: 0.3){
                 callback(UIImage(data: data))
             }

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

@@ -103,6 +103,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 progressThumV.isHidden = false
                 cameraProgressThumV.isHidden = true
                 progreddL.isHidden = false
+                cameraFlipBtn.isHidden = true
 
             case .Video:
                 rscurrentManager = rsvmanager
@@ -110,7 +111,8 @@ public class BFRecordScreenController: BFBaseViewController {
                 progressThumV.isHidden = false
                 cameraProgressThumV.isHidden = true
                 progreddL.isHidden = false
-                
+                cameraFlipBtn.isHidden = true
+
             case .Camera:
                 rscurrentManager = rscmanager
                 recordBtn.setTitle("record_lz".BFLocale, for: .normal)
@@ -119,7 +121,8 @@ public class BFRecordScreenController: BFBaseViewController {
                 cameraProgressThumV.isHidden = false
                 progreddL.isHidden = true
                 rscmanager.cameraProgressV = cameraProgressThumV
-                
+                cameraFlipBtn.isHidden = false
+
             default:
                 break
             }
@@ -136,6 +139,9 @@ public class BFRecordScreenController: BFBaseViewController {
                     rscmanager.rendView.snp.makeConstraints { make in
                         make.edges.equalToSuperview()
                     }
+                    rscmanager.cameraFlipHandle = {[weak cell] isFrontCamera in
+                        (cell as? BFCameraCoverViewCell)?.mirrorCamera(isFrontCamera)
+                    }
                     
                 } else {
                     progressThumV.isHidden = false
@@ -170,6 +176,7 @@ public class BFRecordScreenController: BFBaseViewController {
 
     public var displayLink: CADisplayLink? // 图片素材播放控制
 
+    var canInsertVideo = false
     public var isRecording = false { // 是否正在录音
         didSet {
             withDrawBtn.isHidden = isRecording
@@ -425,6 +432,19 @@ public class BFRecordScreenController: BFBaseViewController {
         btn.titleEdgeInsets = UIEdgeInsets(top: 20, left: -40, bottom: -20, right: 0)
         return btn
     }()
+    
+    
+    // 镜头反转设置
+    lazy var cameraFlipBtn: UIButton = {
+        let btn = UIButton(type: .custom)
+        btn.setImage(imageInRecordScreenKit(by: "flip"), for: .normal)
+//        btn.setTitle("function_cameraFlip".BFLocale, for: .normal)
+        btn.titleLabel?.font = UIFont.systemFont(ofSize: 10)
+        btn.addTarget(self, action: #selector(cameraFlipAction), for: .touchUpInside)
+        btn.imageEdgeInsets = UIEdgeInsets(top: -20, left: 4, bottom: 0, right: -4)
+        btn.titleEdgeInsets = UIEdgeInsets(top: 20, left: -40, bottom: -20, right: 0)
+        return btn
+    }()
 
 
     // 字幕设置面板
@@ -607,6 +627,11 @@ public class BFRecordScreenController: BFBaseViewController {
         super.viewDidLoad()
         _ = disablePopGesture()
 
+        let doubleTapGes = UITapGestureRecognizer(target: self, action: #selector(doubleTapAction(tap:)))
+        doubleTapGes.numberOfTapsRequired = 2
+        doubleTapGes.numberOfTouchesRequired = 1
+        view.addGestureRecognizer(doubleTapGes)
+        
         // 进入活跃状态
         PQNotification.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
         PQNotification.addObserver(self, selector: #selector(routeChangeNofify(nofify:)), name: AVAudioSession.routeChangeNotification, object: nil)
@@ -638,13 +663,13 @@ public class BFRecordScreenController: BFBaseViewController {
         view.addSubview(bottomeView)
 //        view.addSubview(subtitleLabel)
         view.addSubview(playBtn)
-        view.addSubview(avatarView)
+//        view.addSubview(avatarView)
 //        view.addSubview(openCameraBtn)
 //        view.addSubview(drawPinBtn)
         view.addSubview(subtitleBtn)
         view.addSubview(soundSettingBtn)
+        view.addSubview(cameraFlipBtn)
         view.addSubview(subtitleSettingView)
-
         view.addSubview(audioSettingView)
 
         bottomeView.addSubview(progreddL)
@@ -783,6 +808,12 @@ public class BFRecordScreenController: BFBaseViewController {
             make.right.width.height.equalTo(soundSettingBtn)
             make.top.equalTo(soundSettingBtn.snp.bottom).offset(18)
         }
+        
+        cameraFlipBtn.snp.makeConstraints { make in
+            make.left.equalTo(8)
+            make.top.equalTo(soundSettingBtn)
+            make.width.height.equalTo(48)
+        }
 
         withDrawBtn.imageEdgeInsets = UIEdgeInsets(top: -withDrawBtn.imageView!.height, left: 0, bottom: 0, right: -withDrawBtn.titleLabel!.width)
         withDrawBtn.titleEdgeInsets = UIEdgeInsets(top: withDrawBtn.titleLabel!.height + 2, left: -withDrawBtn.imageView!.width, bottom: 0, right: 0)
@@ -1185,6 +1216,18 @@ public class BFRecordScreenController: BFBaseViewController {
 
         audioSettingView.isHidden = false
     }
+    
+    @objc func doubleTapAction(tap:UITapGestureRecognizer) {
+        if currMediaType == .Camera {
+            rscmanager.cameraFlip()
+        }
+    }
+    
+    @objc func cameraFlipAction(){
+        if currMediaType == .Camera {
+            rscmanager.cameraFlip()
+        }
+    }
 
     /// 删除指定段落的所有字幕 数据
     /// - Parameter voiceModel: 删除的音频数据
@@ -1295,6 +1338,11 @@ public class BFRecordScreenController: BFBaseViewController {
         // 录制中不显示播放按钮
         playBtn.isSelected = true
         playBtn.isHidden = true
+        if currMediaType == .Camera {
+            cameraFlipBtn.isHidden = true
+        }
+        
+        
         let cell = collectionView.cellForItem(at: IndexPath(item: currItemModelIndex, section: 0)) as? BFImageCoverViewCell
         if cell?.contentView.viewWithTag(100_100)?.superview == nil {
             cell?.contentView.addSubview(subtitleLabel)
@@ -1308,7 +1356,10 @@ public class BFRecordScreenController: BFBaseViewController {
         }
         if currMediaType == .Video {
             pause()
+        }else if currMediaType == .Camera {
+            cameraFlipBtn.isHidden = false
         }
+        
         beginOnStartBtn = false
 
         BFLog(1, message: "停止录音- \(currentAssetProgress.seconds)")
@@ -1334,15 +1385,6 @@ public class BFRecordScreenController: BFBaseViewController {
         }
         recorderManager?.stopRecord(isCancel: false)
 
-        /*
-         if currentAssetProgress.seconds - (recorderManager?.voiceModel?.startCMTime.seconds ?? 0 ) >= 1.0 {
-             recorderManager?.stopRecord(isCancel: false)
-             changeWithDrawBtnLayout(2)
-         }else{
-             recorderManager?.stopRecord(isCancel: true)
-             changeProgress(progress: Float(recorderManager?.voiceModel?.startCMTime.seconds ?? 0))
-         }
-         */
         if !avatarView.isHidden {
             avatarView.endRecord()
         }
@@ -1676,6 +1718,7 @@ public class BFRecordScreenController: BFBaseViewController {
         
         var startTime: CMTime?
         var endTime: CMTime?
+        canInsertVideo = false
         isStopAtRecordRange = -1
         
         isEndPlay = (CMTimeCompare(currentAssetProgress, rscurrentManager.recordItem?.materialDuraion ?? .zero) >= 0)
@@ -1741,6 +1784,7 @@ public class BFRecordScreenController: BFBaseViewController {
         
         updatePlayBtnStatus()
     }
+    
     func updatePlayBtnStatus(){
         switch currMediaType {
         case .Image:
@@ -1767,7 +1811,7 @@ public class BFRecordScreenController: BFBaseViewController {
             recordBtn.isHidden = isEndPlay ? false : su
         }
         
-        deleteRecordBtn.isHidden = isEndPlay ? true : !su
+        deleteRecordBtn.isHidden = isEndPlay ? true : !(recordBtn.isHidden)
     }
 
     // MARK: - 权限申请

+ 10 - 2
BFRecordScreenKit/Classes/RecordScreen/View/Cell/BFCameraCoverViewCell.swift

@@ -6,6 +6,7 @@
 //
 
 import Foundation
+import GPUImage
 
 open class BFCameraCoverViewCell: BFImageCoverViewCell {
     
@@ -24,10 +25,17 @@ open class BFCameraCoverViewCell: BFImageCoverViewCell {
         }
     }
     
+    public func mirrorCamera(_ isFrontCamera : Bool) {
+        if isFrontCamera{
+            playView.setInputRotation(GPUImageRotationMode(rawValue: 2), at: 0)
+        }else {
+            playView.setInputRotation(GPUImageRotationMode(rawValue: 0), at: 0)
+        }
+
+    }
+    
     public override init(frame: CGRect) {
         super.init(frame: frame)
-        
-        
     }
     
     public required init?(coder _: NSCoder) {

+ 8 - 5
BFRecordScreenKit/Classes/RecordScreen/View/ProgressView/BFCameraProgressView.swift

@@ -65,12 +65,14 @@ class BFCameraProgressView: BFProgressBaseView {
                 wself.progressView.contentView.addSubview(iv)
 
                 if let lastiv = wself.imageViews.last {
-                    iv.frame = CGRect(x: lastiv.rightX, y: lastiv.y, width: 0, height: 50)
+                    let wid = wself.recordItem!.videoStickers.last!.timelineCMOut.seconds * 70.0 / 5.0 - (lastiv.rightX - cScreenWidth / 2.0)
+                    let wid0 = floor(wid * UIScreen.main.scale) /  UIScreen.main.scale
+                    iv.frame = CGRect(x: lastiv.rightX, y: lastiv.y, width: wid0, height: 50)
                     if wself.newRecord {
                         lastiv.isHiddenBord = false
                         wself.newRecord = false
                     }
-                    BFLog(1, message: "frame: \(lastiv.viewWithTag(12333)!.convert(lastiv.viewWithTag(12333)!.bounds     , to: wself.progressView.contentView)), \(iv.frame)")
+                    BFLog(1, message: "frame: new \(wid0)")
                 }else{
                     iv.frame = CGRect(x: cScreenWidth / 2.0, y: 0, width: 0, height: 50)
                 }
@@ -126,15 +128,16 @@ class BFCameraProgressView: BFProgressBaseView {
     }
     
     func updateCellWidth(index:Int, progress:CMTime) {
+        BFLog(1, message: "frame sec: \(progress.seconds)")
         if let sticker = recordItem?.videoStickers.first(where: { mod in
             CMTimeCompare(mod.timelineCMIn, progress) <= 0 &&  CMTimeCompare(mod.timelineCMOut, progress) >= 0
         }) {
             if index < imageViews.count{
                 let lastiv = imageViews[index]
                 let wid = progress.seconds * 70.0 / 5.0 - (lastiv.x - cScreenWidth / 2.0)
-                let wid0 = floor(wid * UIScreen.main.scale) /  UIScreen.main.scale
+                let wid0 = min(floor(wid * UIScreen.main.scale) /  UIScreen.main.scale, 70)
                 
-                if wid0 <= lastiv.width || wid0 > 70{
+                if wid0 <= lastiv.width {
                     return
                 }
                 var frame = lastiv.frame
@@ -145,7 +148,7 @@ class BFCameraProgressView: BFProgressBaseView {
             let p = CGPoint(x: progress.seconds * 70 / 5.0, y: 0)
             progressView.contentOffset = p
             progressView.contentSize = CGSize(width: p.x + cScreenWidth, height: 50)
-            BFLog(1, message: "contentSize: \(progressView.contentSize)")
+            BFLog(1, message: "frame: \(imageViews[index].width), sec: \(progress.seconds)")
         }
     }