Reputation: 6549
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.
Upvotes: 1
Views: 206
Reputation: 13758
If you want to track timeControlStatus
of the AVPlayer
you should observe it with Key-Value Observing instead of handling gestures etc. because AVPlayerViewController has other buttons.
import AVKit
let observer: NSKeyValueObservation?
let url = URL(string: "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8")!
let player = AVPlayer(url: url)
player.play()
let playerController = AVPlayerViewController()
playerController.player = player
observer = player.observe(\.timeControlStatus, options: [.new]) { player, change in
switch player.timeControlStatus {
case .paused:
print("paused")
case .playing:
print("playing")
case .waitingToPlayAtSpecifiedRate:
print("waitingToPlayAtSpecifiedRate")
@unknown default:
break
}
}
PlaygroundPage.current.liveView = playerController
PlaygroundPage.current.needsIndefiniteExecution = true
NOTE:
observer
variable must be stored anywhere on your controller or globally.
Upvotes: 1