LWPlayerView.swift 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //
  2. // LWPlayerView.swift
  3. // SwiftBilibili
  4. //
  5. // Created by 罗文 on 2021/3/28.
  6. // Copyright © 2021年 罗文. All rights reserved.
  7. //
  8. import UIKit
  9. import AVFoundation
  10. final class LWPlayerView: UIView {
  11. //播放器属性
  12. weak private var player: LWPlayer?
  13. weak var controlView: UIView? {
  14. didSet {
  15. if oldValue != controlView{
  16. resetControlView()
  17. }
  18. }
  19. }
  20. override class var layerClass: AnyClass {
  21. return AVPlayerLayer.self
  22. }
  23. //手势属性
  24. public var panGesture: UIPanGestureRecognizer!
  25. public var singleTapGesture: UITapGestureRecognizer!
  26. public var doubleTapGesture: UITapGestureRecognizer!
  27. private var trigger = LWPlayerSlideTrigger.none
  28. private var isHorizontalPan = true
  29. private var currentPosition : TimeInterval?
  30. private var volumeSlider : UISlider!
  31. // MARK: - Life cycle
  32. override init(frame: CGRect) {
  33. super.init(frame: frame)
  34. commonInit()
  35. }
  36. init(controlView: UIView?) {
  37. super.init(frame: .zero)
  38. self.controlView = controlView
  39. commonInit()
  40. }
  41. required init?(coder aDecoder: NSCoder) {
  42. fatalError("init(coder:) has not been implemented")
  43. }
  44. override func layoutSubviews() {
  45. super.layoutSubviews()
  46. self.controlView?.frame = self.bounds
  47. }
  48. // MARK: - public
  49. func config(player:LWPlayer? = nil) {
  50. if let player = player {
  51. (self.layer as! AVPlayerLayer).player = player.player
  52. if let customAction = self.controlView as? LWPlayerCustomAction{
  53. customAction.player = player
  54. }
  55. self.player = player
  56. }
  57. }
  58. // MARK: - private
  59. private func commonInit() {
  60. self.clipsToBounds = true
  61. self.backgroundColor = UIColor.black
  62. self.autoresizingMask = [.flexibleHeight, .flexibleWidth,.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin]
  63. self.controlView?.autoresizingMask = [.flexibleLeftMargin,.flexibleTopMargin,.flexibleRightMargin,.flexibleBottomMargin]
  64. self.addSubview(self.controlView!)
  65. self.panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panDirection(_:)))
  66. self.addGestureRecognizer(self.panGesture)
  67. self.panGesture.delegate = self
  68. self.singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.singleTapGestureTapped(_:)))
  69. self.singleTapGesture.delegate = self
  70. self.singleTapGesture.numberOfTapsRequired = 1
  71. self.singleTapGesture.numberOfTouchesRequired = 1
  72. self.addGestureRecognizer(self.singleTapGesture)
  73. self.doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapGestureTapped(_:)))
  74. self.doubleTapGesture.delegate = self
  75. self.doubleTapGesture.numberOfTapsRequired = 2
  76. self.doubleTapGesture.numberOfTouchesRequired = 1
  77. self.addGestureRecognizer(self.doubleTapGesture)
  78. self.singleTapGesture.require(toFail: self.doubleTapGesture)
  79. }
  80. private func resetControlView() {
  81. controlView?.removeFromSuperview()
  82. self.addSubview(controlView!)
  83. self.setNeedsDisplay()
  84. if let customAction = controlView as? LWPlayerCustomAction {
  85. customAction.player = self.player
  86. }
  87. }
  88. }
  89. //MARK: - 手势方法
  90. extension LWPlayerView {
  91. @objc private func panDirection(_ pan: UIPanGestureRecognizer) {
  92. guard let player = self.player else { return }
  93. let velocityPoint = pan.velocity(in: self)
  94. switch pan.state {
  95. case .began:
  96. let x = abs(velocityPoint.x)
  97. let y = abs(velocityPoint.y)
  98. if x > y {
  99. if let horizontalPanDelegate = controlView as? LWPlayerHorizontalPan,player.canSlideProgress {
  100. isHorizontalPan = true
  101. currentPosition = player.currentTime
  102. horizontalPanDelegate.player(player, progressWillChange: currentPosition ?? 0)
  103. }
  104. }else {
  105. isHorizontalPan = false
  106. if pan.location(in: self).x > self.bounds.size.width / 2 {
  107. trigger = player.slideTrigger.right
  108. } else {
  109. trigger = player.slideTrigger.left
  110. }
  111. }
  112. case .changed:
  113. if isHorizontalPan {
  114. horizontalMoved(velocityPoint.x)
  115. } else {
  116. verticalMoved(velocityPoint.y,player: player, slideType: trigger)
  117. }
  118. case .ended:
  119. if isHorizontalPan {
  120. if let horizontalPanDelegate = controlView as? LWPlayerHorizontalPan, player.canSlideProgress{
  121. if let currentPosition = currentPosition , !currentPosition.isNaN {
  122. horizontalPanDelegate.player(player, progressDidChange: currentPosition)
  123. }
  124. }
  125. }
  126. default:
  127. break
  128. }
  129. }
  130. @objc private func singleTapGestureTapped(_ sender: UIGestureRecognizer) {
  131. guard let player = self.player else { return }
  132. if let gestureRecognizer = controlView as? LWPlayerGestureRecognizer{
  133. gestureRecognizer.player(player, singleTapGestureTapped: sender as! UITapGestureRecognizer)
  134. }
  135. }
  136. @objc private func doubleTapGestureTapped(_ sender: UIGestureRecognizer) {
  137. guard let player = self.player else { return }
  138. if let gestureRecognizer = controlView as? LWPlayerGestureRecognizer{
  139. gestureRecognizer.player(player, doubleTapGestureTapped: sender as! UITapGestureRecognizer)
  140. }
  141. }
  142. private func verticalMoved(_ value: CGFloat, player: LWPlayer, slideType: LWPlayerSlideTrigger) {
  143. switch slideType {
  144. case .volume:
  145. player.systemVolume -= Float(value / 10000)
  146. case .brightness:
  147. UIScreen.main.brightness -= value / 10000
  148. default:
  149. break
  150. }
  151. }
  152. private func horizontalMoved(_ value: CGFloat) {
  153. guard let player = player,
  154. let horizontalPanDelegate = controlView as? LWPlayerHorizontalPan,
  155. player.canSlideProgress
  156. else {
  157. return
  158. }
  159. if let currentPosition = currentPosition,!currentPosition.isNaN,
  160. let duration = player.duration,!duration.isNaN {
  161. let nextPosition = currentPosition + TimeInterval(value) / 100.0 * (duration/400)
  162. if nextPosition > duration {
  163. self.currentPosition = duration
  164. } else if nextPosition < 0 {
  165. self.currentPosition = 0
  166. } else {
  167. self.currentPosition = nextPosition
  168. }
  169. horizontalPanDelegate.player(player, progressDidChange: nextPosition)
  170. }
  171. }
  172. }
  173. extension LWPlayerView: UIGestureRecognizerDelegate {
  174. public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
  175. guard let player = self.player else {
  176. return false
  177. }
  178. if self.singleTapGesture == gestureRecognizer || self.doubleTapGesture == gestureRecognizer {
  179. if let customAction = self.controlView as? LWPlayerCustomAction{//点击控制条
  180. return !customAction.autoHidedControlViews.contains(touch.view!) && !customAction.autoHidedControlViews.contains(touch.view!.superview!)
  181. }
  182. } else if self.panGesture == gestureRecognizer {
  183. if player.displayMode == .float || player.isLive ?? true {
  184. return false
  185. }
  186. return touch.view == self.controlView
  187. }
  188. return true
  189. }
  190. }