fixing PIP mode on iOS

This commit is contained in:
lrusso 2023-08-28 14:55:34 -03:00
parent 6b60428ec7
commit 35256062d9
3 changed files with 31 additions and 23 deletions

View File

@ -4,15 +4,15 @@ import MediaAccessibility
import React
import Foundation
#if TARGET_OS_IOS
#if os(iOS)
class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
private var _onPictureInPictureStatusChanged: RCTDirectEventBlock?
private var _onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
private var _onPictureInPictureStatusChanged: (() -> Void)? = nil
private var _onRestoreUserInterfaceForPictureInPictureStop: (() -> Void)? = nil
private var _restoreUserInterfaceForPIPStopCompletionHandler:((Bool) -> Void)? = nil
private var _pipController:AVPictureInPictureController?
private var _isActive:Bool = false
init(_ onPictureInPictureStatusChanged: @escaping RCTDirectEventBlock, _ onRestoreUserInterfaceForPictureInPictureStop: @escaping RCTDirectEventBlock) {
init(_ onPictureInPictureStatusChanged: (() -> Void)? = nil, _ onRestoreUserInterfaceForPictureInPictureStop: (() -> Void)? = nil) {
_onPictureInPictureStatusChanged = onPictureInPictureStatusChanged
_onRestoreUserInterfaceForPictureInPictureStop = onRestoreUserInterfaceForPictureInPictureStop
}
@ -20,22 +20,20 @@ class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
_onPictureInPictureStatusChanged([ "isActive": NSNumber(value: true)])
_onPictureInPictureStatusChanged()
}
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
_onPictureInPictureStatusChanged([ "isActive": NSNumber(value: false)])
_onPictureInPictureStatusChanged()
}
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
assert(_restoreUserInterfaceForPIPStopCompletionHandler == nil, "restoreUserInterfaceForPIPStopCompletionHandler was not called after picture in picture was exited.")
guard let _onRestoreUserInterfaceForPictureInPictureStop = _onRestoreUserInterfaceForPictureInPictureStop else { return }
_onRestoreUserInterfaceForPictureInPictureStop([:])
_onRestoreUserInterfaceForPictureInPictureStop()
_restoreUserInterfaceForPIPStopCompletionHandler = completionHandler
}
@ -47,7 +45,6 @@ class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
}
func setupPipController(_ playerLayer: AVPlayerLayer?) {
guard playerLayer != nil && AVPictureInPictureController.isPictureInPictureSupported() && _isActive else { return }
// Create new controller passing reference to the AVPlayerLayer
_pipController = AVPictureInPictureController(playerLayer:playerLayer!)
_pipController?.delegate = self

View File

@ -112,15 +112,13 @@ enum RCTPlayerOperations {
}
}
} else { // default. invalid type or "system"
#if os(tvOS)
// Do noting. Fix for tvOS native audio menu language selector
#else
#if os(iOS)
player?.currentItem?.selectMediaOptionAutomatically(in: group)
return
#endif
}
#if os(tvOS)
#if os(iOS)
// Do noting. Fix for tvOS native audio menu language selector
#else
// If a match isn't found, option will be nil and text tracks will be disabled

View File

@ -81,8 +81,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
private let _videoCache:RCTVideoCachingHandler = RCTVideoCachingHandler()
#endif
#if TARGET_OS_IOS
private let _pip:RCTPictureInPicture = RCTPictureInPicture(self.onPictureInPictureStatusChanged, self.onRestoreUserInterfaceForPictureInPictureStop)
#if os(iOS)
private var _pip:RCTPictureInPicture? = nil
#endif
// Events
@ -109,6 +109,14 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc var onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
@objc var onGetLicense: RCTDirectEventBlock?
@objc var onReceiveAdEvent: RCTDirectEventBlock?
@objc func _onPictureInPictureStatusChanged() {
onPictureInPictureStatusChanged?([ "isActive": NSNumber(value: true)])
}
@objc func _onRestoreUserInterfaceForPictureInPictureStop() {
onPictureInPictureStatusChanged?([ "isActive": NSNumber(value: false)])
}
init(eventDispatcher:RCTEventDispatcher!) {
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
@ -118,6 +126,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
_eventDispatcher = eventDispatcher
#if os(iOS)
_pip = RCTPictureInPicture(self._onPictureInPictureStatusChanged, self._onRestoreUserInterfaceForPictureInPictureStop)
#endif
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillResignActive(notification:)),
@ -410,15 +422,15 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
@objc
func setPictureInPicture(_ pictureInPicture:Bool) {
#if TARGET_OS_IOS
_pip.setPictureInPicture(pictureInPicture)
#if os(iOS)
_pip?.setPictureInPicture(pictureInPicture)
#endif
}
@objc
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore:Bool) {
#if TARGET_OS_IOS
_pip.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
#if os(iOS)
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
#endif
}
@ -737,6 +749,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
viewController.view.frame = self.bounds
viewController.player = player
viewController.allowsPictureInPicturePlayback = true
return viewController
}
@ -755,8 +768,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
self.layer.addSublayer(_playerLayer)
}
self.layer.needsDisplayOnBoundsChange = true
#if TARGET_OS_IOS
_pip.setupPipController(_playerLayer)
#if os(iOS)
_pip?.setupPipController(_playerLayer)
#endif
}
}