使用Swift开发一个贝乐虎启蒙App - 视频播放(二)

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战markdown

前言

上一篇咱们把视频播放作好了,如今咱们就来作控制层。那咱们须要哪些控制功能呢?
ide

一、上下滑动屏幕左侧能够设置亮度
二、上下滑动屏幕右侧能够设置音量
三、左右滑动屏幕视频能够快进/快退
四、单击屏幕隐藏/显示上、下、右边的view
五、双击屏幕暂停/播放视频
post

WechatIMG171.jpeg

控制功能

一、先在PlayerViewController里面增长一个PanDirection枚举,用来标识滑动方向

enum PanDirection {
    case unkonw /// 未知
    case horizontal /// 横向移动
    case vertical /// 纵向移动
}
复制代码

二、给player.view添加单击和双击手势

let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
singleTap.delegate = self
singleTap.numberOfTapsRequired = 1
player.view.addGestureRecognizer(singleTap)

let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTap.delegate = self
doubleTap.numberOfTapsRequired = 2
player.view.addGestureRecognizer(doubleTap)

/// 解决点击当前view时候响应其余控件事件
singleTap.delaysTouchesBegan = true
doubleTap.delaysTouchesBegan = true
/// 双击失败响应单击事件
singleTap.require(toFail: doubleTap)

/// 单击
@objc private func handleSingleTap() {

}

/// 双击
@objc private func handleDoubleTap() {
    switch player.playbackState {
        case .stopped:
            player.playFromBeginning()
        case .paused:
            player.playFromCurrentTime()
        case .playing:
            player.pause()
        case .failed:
            player.pause()
    }
}
复制代码

三、当视频播放成功的时候添加UIPanGestureRecognizer手势

func playerReady(_ player: Player) {
    let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panDirection(_:)))
    panRecognizer.delegate = self
    panRecognizer.maximumNumberOfTouches = 1
    panRecognizer.delaysTouchesBegan = true
    panRecognizer.delaysTouchesEnded = true
    panRecognizer.cancelsTouchesInView = true
    player.view.addGestureRecognizer(panRecognizer)
}

@objc private func panDirection(_ pan: UIPanGestureRecognizer) {

    /// 根据在view上Pan的位置,肯定是调音量仍是亮度
    let locationPoint = pan.location(in: player.view)
    /// 咱们要响应水平移动和垂直移动
    /// 根据上次和本次移动的位置,算出一个速率的point
    let veloctyPoint = pan.velocity(in: player.view)

    /// 判断是垂直移动仍是水平移动
    switch pan.state {
    case .began:
        /// 使用绝对值来判断移动的方向
        let x = abs(veloctyPoint.x)
        let y = abs(veloctyPoint.y)
        if x > y { /// 水平移动
            panDirection = .horizontal
            sumTime = Double(player.currentTimeInterval)
            isPlaying = player.playbackState == .playing
            player.pause()
            isDragged = true
        } else {
            panDirection = .vertical
            /// 开始滑动的时候,状态改成正在控制音量
            if (locationPoint.x > player.view.bounds.size.width / 2) {
                self.isVolume = true;
            } else { /// 状态改成显示亮度调节
                self.isVolume = false;
            }
        }
    case .changed:
        switch panDirection {
        case .horizontal:
            horizontalMoved(value: veloctyPoint.x)
        case .vertical:
            verticalMoved(value: veloctyPoint.y) /// 垂直移动方法只要y方向的值
        default:
            break
        }
    case .ended:
        switch panDirection {
        case .horizontal:
            if isPlaying {
                player.playFromCurrentTime()
                isPlaying = false
            }
            isDragged = false
            sumTime = 0
        case .vertical:
            /// 垂直移动结束后,把状态改成再也不控制音量
            isVolume = false
        default:
            break
        }
    default:
        break
    }
}

/// pan垂直移动的方法,设置音量/亮度
private func verticalMoved(value: CGFloat) {
    isVolume ? (volumeViewSlider?.value -= Float(value / 10000)) : (UIScreen.main.brightness -= value / 10000)
}

/// pan水平移动的方法,快进/快退
private func horizontalMoved(value: CGFloat) {
    /// 每次滑动须要叠加时间
    sumTime += Double(value) / 300
    /// 须要限定sumTime的范围
    let totalTime = player.maximumDuration
    if sumTime > totalTime { sumTime = totalTime }
    if sumTime < 0 { sumTime = 0 }
    player.seek(to: CMTime(seconds: sumTime, preferredTimescale: CMTimeScale(1 * NSEC_PER_SEC)))
}

extension PlayerViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        guard let v = touch.view else { return false }
        if v.isKind(of: UISlider.self) {
            return false
        }
        if v.isKind(of: UIButton.self) {
            return false
        }
        return true
    }
}
复制代码

设置音量以前要获取MPVolumeView里面的UISlider来控制音量ui

let volumeView = MPVolumeView()
volumeViewSlider = nil
for v in volumeView.subviews {
    if v.classForCoder.description() == "MPVolumeSlider", let slider = v as? UISlider {
        volumeViewSlider = slider
    }
}

do {
    /// 使用这个category的应用不会随着手机静音键打开而静音,可在手机静音下播放声音
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
} catch {}
复制代码

下面是效果展现。手机录屏录时,设置屏幕亮度在录完视频里面是没有效果的 视频播放1.gifspa

相关文章
相关标签/搜索