這是我參與8月更文挑戰的第9天,活動詳情查看:8月更文挑戰markdown
上一篇咱們把視頻播放作好了,如今咱們就來作控制層。那咱們須要哪些控制功能呢?
ide
一、上下滑動屏幕左側能夠設置亮度
二、上下滑動屏幕右側能夠設置音量
三、左右滑動屏幕視頻能夠快進/快退
四、單擊屏幕隱藏/顯示上、下、右邊的view
五、雙擊屏幕暫停/播放視頻
post
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 {}
複製代碼
下面是效果展現。手機錄屏錄時,設置屏幕亮度在錄完視頻裏面是沒有效果的 spa