fix(ios): call PictureInPicture callbacks with native controls (#3603)
* fix(ios): call PictureInPictureStatusChanged callback with native controls We add RCTPlayerObserver as playerViewController delegate to be notified with PiP lifecycle should partially fix #3602 * fix(ios): call onRestoreUserInterfaceForPictureInPictureStop callback with native controls should partially fix #3602
This commit is contained in:
parent
2a858df8bc
commit
051e884c8f
@ -27,11 +27,14 @@ protocol RCTPlayerObserverHandler: RCTPlayerObserverHandlerObjc {
|
||||
func handleViewControllerOverlayViewFrameChange(overlayView: UIView, change: NSKeyValueObservedChange<CGRect>)
|
||||
func handleTracksChange(playerItem: AVPlayerItem, change: NSKeyValueObservedChange<[AVPlayerItemTrack]>)
|
||||
func handleLegibleOutput(strings: [NSAttributedString])
|
||||
func handlePictureInPictureEnter()
|
||||
func handlePictureInPictureExit()
|
||||
func handleRestoreUserInterfaceForPictureInPictureStop()
|
||||
}
|
||||
|
||||
// MARK: - RCTPlayerObserver
|
||||
|
||||
class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPlayerItemLegibleOutputPushDelegate {
|
||||
class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPlayerItemLegibleOutputPushDelegate, AVPlayerViewControllerDelegate {
|
||||
weak var _handlers: RCTPlayerObserverHandler?
|
||||
|
||||
var player: AVPlayer? {
|
||||
@ -105,6 +108,7 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
||||
private var _playerLayerReadyForDisplayObserver: NSKeyValueObservation?
|
||||
private var _playerViewControllerOverlayFrameObserver: NSKeyValueObservation?
|
||||
private var _playerTracksObserver: NSKeyValueObservation?
|
||||
private var _restoreUserInterfaceForPIPStopCompletionHandler: ((Bool) -> Void)?
|
||||
|
||||
deinit {
|
||||
if let _handlers {
|
||||
@ -192,11 +196,14 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
||||
options: [.new, .old],
|
||||
changeHandler: _handlers.handleViewControllerOverlayViewFrameChange
|
||||
)
|
||||
|
||||
playerViewController.delegate = self
|
||||
}
|
||||
|
||||
func removePlayerViewControllerObservers() {
|
||||
_playerViewControllerReadyForDisplayObserver?.invalidate()
|
||||
_playerViewControllerOverlayFrameObserver?.invalidate()
|
||||
playerViewController?.delegate = nil
|
||||
}
|
||||
|
||||
func addPlayerLayerObserver() {
|
||||
@ -288,4 +295,34 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
||||
NotificationCenter.default.removeObserver(_handlers)
|
||||
}
|
||||
}
|
||||
|
||||
func playerViewControllerDidStartPictureInPicture(_: AVPlayerViewController) {
|
||||
guard let _handlers else { return }
|
||||
|
||||
_handlers.handlePictureInPictureEnter()
|
||||
}
|
||||
|
||||
func playerViewControllerDidStopPictureInPicture(_: AVPlayerViewController) {
|
||||
guard let _handlers else { return }
|
||||
|
||||
_handlers.handlePictureInPictureExit()
|
||||
}
|
||||
|
||||
func playerViewController(
|
||||
_: AVPlayerViewController,
|
||||
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
|
||||
) {
|
||||
guard let _handlers else { return }
|
||||
|
||||
_handlers.handleRestoreUserInterfaceForPictureInPictureStop()
|
||||
|
||||
_restoreUserInterfaceForPIPStopCompletionHandler = completionHandler
|
||||
}
|
||||
|
||||
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore: Bool) {
|
||||
guard let _restoreUserInterfaceForPIPStopCompletionHandler else { return }
|
||||
|
||||
_restoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||
self._restoreUserInterfaceForPIPStopCompletionHandler = nil
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +128,18 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
onPictureInPictureStatusChanged?(["isActive": NSNumber(value: false)])
|
||||
}
|
||||
|
||||
func handlePictureInPictureEnter() {
|
||||
onPictureInPictureStatusChanged?(["isActive": NSNumber(value: true)])
|
||||
}
|
||||
|
||||
func handlePictureInPictureExit() {
|
||||
onPictureInPictureStatusChanged?(["isActive": NSNumber(value: false)])
|
||||
}
|
||||
|
||||
func handleRestoreUserInterfaceForPictureInPictureStop() {
|
||||
onRestoreUserInterfaceForPictureInPictureStop?([:])
|
||||
}
|
||||
|
||||
func isPipEnabled() -> Bool {
|
||||
return _pictureInPictureEnabled
|
||||
}
|
||||
@ -606,7 +618,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
@objc
|
||||
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore: Bool) {
|
||||
#if os(iOS)
|
||||
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||
if _pip != nil {
|
||||
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||
} else {
|
||||
_playerObserver.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user