浏览代码

调速完成

南鑫林 5 年之前
父节点
当前提交
7b4dac5efd

+ 1 - 1
RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj

@@ -4598,9 +4598,9 @@
 		A7EE5ACD236C131C00309931 /* PublishNewView */ = {
 			isa = PBXGroup;
 			children = (
+				A7EE5AD0236C131C00309931 /* PublishNewVideoPhotoView.swift */,
 				A7EE5ACE236C131C00309931 /* PublishNewRecorderPreview.swift */,
 				A7EE5ACF236C131C00309931 /* PublishNewVideoPhotoSetView.swift */,
-				A7EE5AD0236C131C00309931 /* PublishNewVideoPhotoView.swift */,
 			);
 			path = PublishNewView;
 			sourceTree = "<group>";

+ 0 - 2
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishEditNew/View/PublishEditNew/PublishEditNewVideoPreView.swift

@@ -61,8 +61,6 @@ class PublishEditNewVideoPreView: BaseView {
         addGestureRecognizer(tap)
     }
     
-    
-    
     /// 移除手势
     func removetap() {
         removeGestureRecognizer(tap)

+ 117 - 4
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishEditNew/View/PublishEditNew/PublishEditNewVideoSetView.swift

@@ -7,6 +7,7 @@
 //
 
 import UIKit
+import JXSegmentedView
 
 class PublishEditNewVideoSetView: BaseView {
 
@@ -23,6 +24,8 @@ class PublishEditNewVideoSetView: BaseView {
         addSubview(speedRegulationButton)
         // 播放进度条
         addSubview(playProgressView)
+        // 调速的View
+        addSubview(segmentedView)
         // 左滑手势
         addLeftSwipe()
         // 右滑手势
@@ -74,13 +77,20 @@ class PublishEditNewVideoSetView: BaseView {
         
         // 播放进度View
         playProgressView.snp.makeConstraints { (make) in
-            make.bottom.equalTo(-25)
+            make.bottom.equalTo(-(kSafeTabBarHeight+30))
             make.left.right.equalToSuperview()
             make.height.equalTo(20)
         }
+        
+        // 调速的View
+        segmentedView.snp.makeConstraints { (make) in
+            make.bottom.equalTo(-(98+kSafeTabBarHeight))
+            make.left.equalTo(14)
+            make.right.equalTo(-14)
+            make.height.equalTo(40)
+        }
     }
     
-    
     /// 返回按钮
     lazy var backButton: UIButton = {
         let backButton = UIButton(type: UIButton.ButtonType.custom)
@@ -115,14 +125,13 @@ class PublishEditNewVideoSetView: BaseView {
     lazy var musicButton: UIButton = {
         let musicButton = UIButton()
         musicButton.setImage(kImage(name: "video_ico_music"), for: UIControl.State.normal)
-        musicButton.setImage(kImage(name: "video_ico_music_pre"), for: UIControl.State.highlighted)
+        musicButton.setImage(kImage(name: "video_ico_music_pre"), for: UIControl.State.selected)
         musicButton.setTitle("音乐", for: UIControl.State.normal)
         musicButton.setTitleColor(kffffffColor, for: UIControl.State.normal)
         musicButton.titleLabel?.font = kRegularFont12
         return musicButton
     }()
     
-    
     /// 调速
     lazy var speedRegulationButton: UIButton = {
         let speedRegulationButton = UIButton()
@@ -140,6 +149,50 @@ class PublishEditNewVideoSetView: BaseView {
         return playProgressView
     }()
     
+    //1.初始化JXSegmentedViewx
+    lazy var segmentedView: JXSegmentedView = {
+        let segmentedView = JXSegmentedView()
+        segmentedView.backgroundColor = k000000Color.withAlphaComponent(0.3)
+        segmentedView.delegate = self
+        segmentedView.dataSource = segmentedDataSource
+        segmentedView.indicators = [indicator]
+        segmentedView.selectItemAt(index: 2)
+        segmentedView.defaultSelectedIndex = 2
+        segmentedView.cornerRadius = 20
+        segmentedView.masksToBounds = true
+        segmentedView.alpha = 0
+        return segmentedView
+    }()
+    
+    //2.初始化dataSource
+    private lazy var segmentedDataSource: JXSegmentedTitleDataSource = {
+        let segmentedDataSource = JXSegmentedTitleDataSource()
+        segmentedDataSource.titles = ["极慢","慢","标准","快","极快"]
+        segmentedDataSource.isTitleColorGradientEnabled = true
+        segmentedDataSource.isItemSpacingAverageEnabled = true
+        segmentedDataSource.isTitleZoomEnabled = true
+        segmentedDataSource.titleNormalColor = kffffffColor
+        segmentedDataSource.titleSelectedColor = k333333Color
+        segmentedDataSource.titleNormalFont = kRegularFont14!
+        segmentedDataSource.titleSelectedFont = kRegularFont14
+        segmentedDataSource.isTitleStrokeWidthEnabled = false
+        segmentedDataSource.isTitleMaskEnabled = true
+        segmentedDataSource.itemSpacing = 0
+        segmentedDataSource.itemContentWidth = (kScreenWidth-28)/5
+        //reloadData(selectedIndex:)方法一定要调用,方法内部会刷新数据源数组
+        segmentedDataSource.reloadData(selectedIndex: 2)
+        return segmentedDataSource
+    }()
+    
+    //3.初始化指示器indicator
+    private lazy var indicator: JXSegmentedIndicatorBackgroundView = {
+        let indicator = JXSegmentedIndicatorBackgroundView()
+        indicator.indicatorColor = .white
+        indicator.indicatorHeight = 40
+        indicator.backgroundWidthIncrement = 0
+        return indicator
+    }()
+    
     /// 左滑手势
     lazy var leftSwipe: UISwipeGestureRecognizer = {
         let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipeAction))
@@ -182,4 +235,64 @@ class PublishEditNewVideoSetView: BaseView {
         }
     }
     
+    /// 点击手势
+    lazy var tap: UITapGestureRecognizer = {
+        let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
+        tap.numberOfTapsRequired = 1
+        tap.numberOfTouchesRequired = 1
+        return tap
+    }()
+    
+    /// 添加轻点手势
+    func addTap() {
+        addGestureRecognizer(tap)
+    }
+    
+    /// 移除手势
+    func removetap() {
+        removeGestureRecognizer(tap)
+    }
+    
+    /// 点击手势
+    typealias TapClosure = () -> Void
+    var tapClosure : TapClosure?
+    @objc func tapAction() {
+        if let tapClosure = tapClosure {
+            tapClosure()
+        }
+    }
+    
+    /// 调速
+    typealias SpeedClosure = (Int) -> Void
+    var speedClosure : SpeedClosure?
 }
+
+extension PublishEditNewVideoSetView : JXSegmentedViewDelegate {
+ 
+    //点击选中或者滚动选中都会调用该方法。适用于只关心选中事件,而不关心具体是点击还是滚动选中的情况。
+    func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) {
+        if let speedClosure = speedClosure {
+            speedClosure(index)
+        }
+    }
+    
+    // 点击选中的情况才会调用该方法
+    func segmentedView(_ segmentedView: JXSegmentedView, didClickSelectedItemAt index: Int) {
+        //传递didClickSelectedItemAt事件给listContainerView,必须调用!!!
+    }
+    
+    // 滚动选中的情况才会调用该方法(未支持滚动选中)
+    func segmentedView(_ segmentedView: JXSegmentedView, didScrollSelectedItemAt index: Int) {
+        print("\n------滚动选中\(index)")
+    }
+    
+    // 正在滚动中的回调
+    func segmentedView(_ segmentedView: JXSegmentedView, scrollingFrom leftIndex: Int, to rightIndex: Int, percent: CGFloat) {
+    }
+    
+    /// 是否允许点击选中目标index的item
+    func segmentedView(_ segmentedView: JXSegmentedView, canClickItemAt index: Int) -> Bool {
+        return true
+    }
+}
+

+ 155 - 12
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishEditNew/View/PublishEditNew/PublishEditNewVideoView.swift

@@ -8,6 +8,7 @@
 
 import UIKit
 import RxSwift
+import RxCocoa
 
 class PublishEditNewVideoView: UIView {
 
@@ -23,6 +24,7 @@ class PublishEditNewVideoView: UIView {
     }
     weak var observe : NSObjectProtocol?
     var taskPath : String?
+    var isPlaying : Bool = true
     
     override init(frame: CGRect) {
         super.init(frame: frame)
@@ -57,13 +59,79 @@ class PublishEditNewVideoView: UIView {
     
     /// 设置数据
     func setupData() {
-        //播放器视频
+        publishEditNewVideoSetView.playProgressView.slider.maximumValue =  Float(player?.getDuration() ?? 0.0)
+        // 播放器视频
         player?.play()
         // 返回
         publishEditNewVideoSetView.backButton.rx.tap.subscribe(onNext: { (_) in
             UIViewController.topMost?.navigationController?.popViewController(animated: true)
         }).disposed(by: disposeBag)
         
+        // 调速view
+        publishEditNewVideoSetView.speedRegulationButton.rx.tap.subscribe(onNext: { [weak self] (_) in
+            guard let strongSelf = self else { return }
+            if strongSelf.publishEditNewVideoSetView.segmentedView.alpha == 0 {
+                strongSelf.showHiddenSegmentedView(isHidden: false)
+            } else if strongSelf.publishEditNewVideoSetView.segmentedView.alpha == 1 {
+                strongSelf.showHiddenSegmentedView(isHidden: true)
+            }
+
+        }).disposed(by: disposeBag)
+        
+        //调速
+        publishEditNewVideoSetView.speedClosure = {
+            [weak self] index in
+            guard let strongSelf = self else { return }
+            strongSelf.speedPlaybackMultiple(index: index)
+        }
+        
+        // 播放/暂停
+        publishEditNewVideoSetView.playProgressView.playButton.rx.tap.subscribe(onNext: { [weak self] (_) in
+            guard let strongSelf = self else { return }
+            if strongSelf.player?.isPlaying() ?? false {
+                strongSelf.pausePlay()
+            }else {
+                strongSelf.resumePlay()
+            }
+        }).disposed(by: disposeBag)
+        // slider位置
+        publishEditNewVideoSetView.playProgressView.sliderValueChangedClosure = {
+            [weak self] in
+            guard let strongSelf = self else { return }
+            strongSelf.pausePlay()
+            strongSelf.isPlaying = true
+            strongSelf.player?.seek(strongSelf.publishEditNewVideoSetView.playProgressView.slider.value)
+            strongSelf.sliderTime(playSec: Double(strongSelf.publishEditNewVideoSetView.playProgressView.slider.value))
+        }
+        
+        // slider滑动停止
+        publishEditNewVideoSetView.playProgressView.sliderActionClosure = {
+            [weak self] in
+            guard let strongSelf = self else { return }
+            if strongSelf.isPlaying {
+                strongSelf.resumePlay()
+            }
+        }
+        
+        // 点击手势
+        editorPreview.tapClosure = {
+            [weak self] in
+            guard let strongSelf = self else { return }
+//            if  strongSelf.effectFilterBeautyView.alpha == 1 {
+//                // 隐藏滤镜
+//                strongSelf.effectFilterBeautyViewisHidden(isHidden: true)
+//            }
+//
+//            if  strongSelf.musicView.alpha == 1 {
+//                // 隐藏音乐
+//                strongSelf.musicViewisHidden(isHidden: true)
+//            }
+            // 隐藏调速
+            if  strongSelf.publishEditNewVideoSetView.segmentedView.alpha == 1 {
+                strongSelf.showHiddenSegmentedView(isHidden: true)
+            }
+        }
+        
     }
     
     /// 编辑
@@ -109,33 +177,108 @@ class PublishEditNewVideoView: UIView {
     
 }
 
+extension PublishEditNewVideoView {
+    
+    
+    /// 暂停播放
+    func pausePlay() {
+        player?.pause()
+        isPlaying = false
+        publishEditNewVideoSetView.playProgressView.playButton.isSelected = true
+
+    }
+    
+    /// 继续播放
+    func resumePlay() {
+        player?.resume()
+        isPlaying = true
+        publishEditNewVideoSetView.playProgressView.playButton.isSelected = false
+    }
+    
+    /// 滑块需要显示的时间
+    /// - Parameter playSec: 时间
+    func sliderTime(playSec: Double) {
+        let d : Int = Int(playSec)
+        let m : Int = Int(d / 60)
+        let s : Int = Int(d % 60)
+        publishEditNewVideoSetView.playProgressView.startTimeLabel.text = String(format: "%02d:%02d", m,s)
+        let endPlaySec = (player?.getDuration() ?? 0) - playSec
+        let d1 : Int = Int(endPlaySec)
+        let m1 : Int = Int(d1 / 60)
+        let s1 : Int = Int(d1 % 60)
+        publishEditNewVideoSetView.playProgressView.endTimeLabel.text = String(format: "%02d:%02d", m1,s1)
+    }
+    
+    /// 调整速度
+    /// - Parameter index: 速度
+    func speedPlaybackMultiple(index:Int) {
+        editor?.removeTimeFilter()
+        let timeFilter = AliyunEffectTimeFilter()
+        timeFilter.type = .speed
+        switch index {
+        case 0:
+            timeFilter.param = 0.5
+        case 1:
+            timeFilter.param = 0.75
+        case 2:
+            timeFilter.param = 1.0
+        case 3:
+            timeFilter.param = 1.5
+        case 4:
+            timeFilter.param = 2.0
+        default:
+            break
+        }
+        editor?.apply(timeFilter)
+        resumePlay()
+        publishEditNewVideoSetView.playProgressView.slider.maximumValue =  Float(player?.getDuration() ?? 0.0)
+
+    }
+    
+    
+    /// 显示/隐层 SegmentedView
+    func showHiddenSegmentedView(isHidden:Bool) {
+        if isHidden {
+            publishEditNewVideoSetView.removetap()
+        }else {
+            publishEditNewVideoSetView.addTap()
+        }
+        UIView.animate(withDuration: 0.3) {
+            [weak self] in
+            guard let strongSelf = self else { return }
+            if isHidden {
+                strongSelf.publishEditNewVideoSetView.segmentedView.alpha = 0
+            }else {
+                strongSelf.publishEditNewVideoSetView.segmentedView.alpha = 1
+            }
+        }
+
+    }
+    
+}
+
 
 extension PublishEditNewVideoView : AliyunIPlayerCallback {
     
     
     /// 播放结束
     func playerDidEnd() {
-        _ = player?.replay()
+        publishEditNewVideoSetView.playProgressView.slider.value = Float(0)
+        // 重复播放
+        player?.replay()
     }
     
-    
     /// 播放进度
     /// - Parameters:
     ///   - playSec: 播放时间轴上的位置。
     ///   - streamSec: 视频流上的位置。
     func playProgress(_ playSec: Double, streamProgress streamSec: Double) {
-        
-    }
-    
-    
-    /// 播放进度
-    /// - Parameter sec: s
-    func playProgress(_ sec: Double) {
-        
+        publishEditNewVideoSetView.playProgressView.slider.value = Float(playSec)
+        sliderTime(playSec: playSec)
     }
     
     func playError(_ errorCode: Int32) {
-        
+        SwiftProgressHUD.shared().showText("播放有误")
     }
     
     func seekDidEnd() {

+ 25 - 5
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishEditNew/View/PublishEditNewPlayProgressView/PublishEditNewPlayProgressView.swift

@@ -20,7 +20,7 @@ class PublishEditNewPlayProgressView: BaseView {
     override func setupLayouts() {
         playButton.snp.makeConstraints { (make) in
             make.centerY.equalToSuperview()
-            make.left.equalTo(-14)
+            make.left.equalTo(14)
             make.size.equalTo(18)
         }
         startTimeLabel.snp.makeConstraints { (make) in
@@ -35,9 +35,8 @@ class PublishEditNewPlayProgressView: BaseView {
             make.width.equalTo(41)
             make.height.equalTo(15)
         }
-        
         slider.snp.makeConstraints { (make) in
-            make.centerY.equalToSuperview()
+            make.top.equalTo(7.5)
             make.height.equalTo(16)
             make.left.equalTo(startTimeLabel.snp.right).offset(5)
             make.right.equalTo(endTimeLabel.snp.left).offset(-5)
@@ -45,7 +44,9 @@ class PublishEditNewPlayProgressView: BaseView {
     }
     
     override func setupData() {
-        
+        slider.addTarget(self, action: #selector(sliderValueChanged), for: UIControl.Event.valueChanged)
+        slider.addTarget(self, action: #selector(sliderAction), for: UIControl.Event.touchUpInside)
+        slider.addTarget(self, action: #selector(sliderAction), for: UIControl.Event.touchUpOutside)
     }
     
     /// 播放
@@ -79,10 +80,29 @@ class PublishEditNewPlayProgressView: BaseView {
     /// 播放进度滑块
     lazy var slider: PublishNewUISlider = {
         let slider = PublishNewUISlider()
-        slider.thumbTintColor = kffffffColor
+        slider.setThumbImage(kImage(name: "music_btn_dot"), for: UIControl.State.normal)
         slider.minimumTrackTintColor = kffffffColor
         slider.maximumTrackTintColor = k000000Color.withAlphaComponent(0.3)
+        slider.value = 0
         return slider
     }()
+    
+    typealias SliderValueChangedClosure = () -> Void
+    var sliderValueChangedClosure : SliderValueChangedClosure?
+    
+    typealias SliderActionClosure = () -> Void
+    var sliderActionClosure : SliderActionClosure?
+    
+    @objc func sliderValueChanged() {
+        if let sliderValueChangedClosure = sliderValueChangedClosure {
+            sliderValueChangedClosure()
+        }
+    }
+    
+    @objc func sliderAction() {
+        if let sliderActionClosure = sliderActionClosure {
+            sliderActionClosure()
+        }
+    }
 
 }

+ 0 - 10
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishEditNew/View/PublishEditNewPlayProgressView/PublishNewUISlider.swift

@@ -18,15 +18,5 @@ class PublishNewUISlider: UISlider {
         self.cornerRadius = 2.5
         return boundsNew
     }
-    
-    ///  改变滑块的触摸范围
-    /// - Parameters:
-    ///   - bounds: bounds
-    ///   - rect: 范围
-    ///   - value: 值
-    override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
-        let rectNew = CGRect(x: rect.origin.x - 5, y: rect.origin.y, width: rect.size.width + 10, height: rect.size.height)
-        return super.thumbRect(forBounds: bounds, trackRect: rectNew, value: value).insetBy(dx: 5, dy: 5)
-    }
 
 }

+ 2 - 2
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishNew/View/PublishNewEffect/PublishNewEffectFilterBeautyView/PublishNewEffectFilterBeautyView.swift

@@ -72,7 +72,7 @@ class PublishNewEffectFilterBeautyView: BaseView {
         let segmentedView = JXSegmentedView()
         segmentedView.backgroundColor = .clear
         segmentedView.delegate = self
-        segmentedView.dataSource = segmentedDataSourceAlbum
+        segmentedView.dataSource = segmentedDataSource
         segmentedView.indicators = [indicator]
         segmentedView.selectItemAt(index: 0)
         segmentedView.defaultSelectedIndex = 0
@@ -80,7 +80,7 @@ class PublishNewEffectFilterBeautyView: BaseView {
     }()
     
     //2.初始化dataSource
-    private lazy var segmentedDataSourceAlbum: JXSegmentedTitleDataSource = {
+    private lazy var segmentedDataSource: JXSegmentedTitleDataSource = {
         let segmentedDataSource = JXSegmentedTitleDataSource()
         segmentedDataSource.titles = ["滤镜","美颜"]
         segmentedDataSource.isTitleColorGradientEnabled = true

+ 1 - 2
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishNew/View/PublishNewView/PublishNewVideoPhotoView.swift

@@ -182,7 +182,6 @@ class PublishNewVideoPhotoView: BaseView {
            
         }
         
-        
         // 左滑 滤镜 加 1
         recorderPreview.leftSwipeClosure = {
             [weak self] in
@@ -217,7 +216,7 @@ class PublishNewVideoPhotoView: BaseView {
         }
         // 当进入Active状态
         observe = NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: OperationQueue.main) {[weak self] (_) in
-            self?.recorder?.stopPreview()
+            self?.recorder?.startPreview()
         }
         
     }

+ 9 - 4
RainbowPlanet/RainbowPlanet/Modules/PublishNewModule/PublishNew/ViewController/PublishNewViewController.swift

@@ -40,6 +40,10 @@ class PublishNewViewController: BaseViewController {
         setupLayouts()
     }
     
+    override func viewDidAppear(_ animated: Bool) {
+        
+    }
+    
     override func setupViews() {
         navigationBar.isHidden = true
         view.addSubview(scrollView)
@@ -179,13 +183,14 @@ class PublishNewViewController: BaseViewController {
     func setRecorder(index:Int,isStartPreview:Bool,duration:TimeInterval) {
         PublishNewViewModel.shared.publishNewRecorderType = PublishNewViewModel.PublishNewRecorderType(rawValue: index)!
         if isStartPreview {
+
             // 开始预览摄像头
-            publishNewVideoPhotoView.recorder?.startPreview()
             scrollView.setContentOffset(CGPoint(x: kScreenWidth, y:0), animated: true)
             segmentedDataSourceVideoPhoto.reloadData(selectedIndex: index)
             segmentedView.dataSource = segmentedDataSourceVideoPhoto
             DispatchQueue.main.async {
                 [weak self] in
+                self?.publishNewVideoPhotoView.recorder?.startPreview()
                 if self?.statusBarStyle != .lightContent {
                     self?.statusBarStyle = .lightContent
                 }
@@ -200,13 +205,13 @@ class PublishNewViewController: BaseViewController {
             }
 
         }else {
-            //停止预览摄像头
-            publishNewVideoPhotoView.recorder?.stopPreview()
             scrollView.setContentOffset(CGPoint(x: 0, y:0), animated: true)
             segmentedDataSourceAlbum.reloadData(selectedIndex: index)
-            self.segmentedView.dataSource = segmentedDataSourceAlbum
+            segmentedView.dataSource = segmentedDataSourceAlbum
             DispatchQueue.main.async {
                 [weak self] in
+                //停止预览摄像头
+                self?.publishNewVideoPhotoView.recorder?.stopPreview()
                 if self?.statusBarStyle != .default {
                     self?.statusBarStyle = .default
                 }