I have added a tapGestureRecognizer for the Play/Pause button and it works on a custom player (meaning a AVPlayer inserted in a ViewController instance) as such:
lazy var playPauseButtonTap: UITapGestureRecognizer = {
let gesture = UITapGestureRecognizer(target: self, action: #selector(playPauseTapped))
gesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)]
return gesture
}()
@objc private func playPauseTapped() {
print("HELLO PLAY PAUSE TAPPED")
togglePlayPause()
}
private func togglePlayPause() {
switch avPlayer.timeControlStatus {
case .playing:
avPlayer.pause()
case .paused:
avPlayer.play()
case .waitingToPlayAtSpecifiedRate:
break
@unknown default:
break
}
}
override func viewDidLoad() {
super.viewDidLoad()
let playerLayer = AVPlayerLayer(player: avPlayer)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
avPlayer.play()
self.view.addGestureRecognizer(playPauseButtonTap)
}
This works! But when the same code is run on a class that inherits from AVPlayerViewController (except the part where we insert the AVPlayerLayer because AVPlayerViewController handles that part), when the button is tapped to pause, the gesture recognizer code won't get called, when the button is tapped to play/resume it DOES get called.
I need to know when the user pauses playback. Is there any way to get this to work using the AVPlayerViewController?
I'm not looking to do swizzling or use any private APIs as Apple will not take that lightly however, I'd be interested to learn if anyone has made it work using some hacky solution that way.
NOTE: I also found out if you have this call: UIApplication.shared.beginReceivingRemoteControlEvents() in your app, this makes a gesture recognizer completely ignore the play/pause button taps.
Thanks in advance.
If you want to track
timeControlStatusof theAVPlayeryou should observe it with Key-Value Observing instead of handling gestures etc. because AVPlayerViewController has other buttons.