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 handleViewControllerOverlayViewFrameChange(overlayView: UIView, change: NSKeyValueObservedChange<CGRect>)
|
||||||
func handleTracksChange(playerItem: AVPlayerItem, change: NSKeyValueObservedChange<[AVPlayerItemTrack]>)
|
func handleTracksChange(playerItem: AVPlayerItem, change: NSKeyValueObservedChange<[AVPlayerItemTrack]>)
|
||||||
func handleLegibleOutput(strings: [NSAttributedString])
|
func handleLegibleOutput(strings: [NSAttributedString])
|
||||||
|
func handlePictureInPictureEnter()
|
||||||
|
func handlePictureInPictureExit()
|
||||||
|
func handleRestoreUserInterfaceForPictureInPictureStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - RCTPlayerObserver
|
// MARK: - RCTPlayerObserver
|
||||||
|
|
||||||
class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPlayerItemLegibleOutputPushDelegate {
|
class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPlayerItemLegibleOutputPushDelegate, AVPlayerViewControllerDelegate {
|
||||||
weak var _handlers: RCTPlayerObserverHandler?
|
weak var _handlers: RCTPlayerObserverHandler?
|
||||||
|
|
||||||
var player: AVPlayer? {
|
var player: AVPlayer? {
|
||||||
@ -105,6 +108,7 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
|||||||
private var _playerLayerReadyForDisplayObserver: NSKeyValueObservation?
|
private var _playerLayerReadyForDisplayObserver: NSKeyValueObservation?
|
||||||
private var _playerViewControllerOverlayFrameObserver: NSKeyValueObservation?
|
private var _playerViewControllerOverlayFrameObserver: NSKeyValueObservation?
|
||||||
private var _playerTracksObserver: NSKeyValueObservation?
|
private var _playerTracksObserver: NSKeyValueObservation?
|
||||||
|
private var _restoreUserInterfaceForPIPStopCompletionHandler: ((Bool) -> Void)?
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
if let _handlers {
|
if let _handlers {
|
||||||
@ -192,11 +196,14 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
|||||||
options: [.new, .old],
|
options: [.new, .old],
|
||||||
changeHandler: _handlers.handleViewControllerOverlayViewFrameChange
|
changeHandler: _handlers.handleViewControllerOverlayViewFrameChange
|
||||||
)
|
)
|
||||||
|
|
||||||
|
playerViewController.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
func removePlayerViewControllerObservers() {
|
func removePlayerViewControllerObservers() {
|
||||||
_playerViewControllerReadyForDisplayObserver?.invalidate()
|
_playerViewControllerReadyForDisplayObserver?.invalidate()
|
||||||
_playerViewControllerOverlayFrameObserver?.invalidate()
|
_playerViewControllerOverlayFrameObserver?.invalidate()
|
||||||
|
playerViewController?.delegate = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPlayerLayerObserver() {
|
func addPlayerLayerObserver() {
|
||||||
@ -288,4 +295,34 @@ class RCTPlayerObserver: NSObject, AVPlayerItemMetadataOutputPushDelegate, AVPla
|
|||||||
NotificationCenter.default.removeObserver(_handlers)
|
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)])
|
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 {
|
func isPipEnabled() -> Bool {
|
||||||
return _pictureInPictureEnabled
|
return _pictureInPictureEnabled
|
||||||
}
|
}
|
||||||
@ -606,7 +618,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
@objc
|
@objc
|
||||||
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore: Bool) {
|
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore: Bool) {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
|
if _pip != nil {
|
||||||
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||||
|
} else {
|
||||||
|
_playerObserver.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user