diff --git a/ios/Video/Features/RCTPictureInPicture.swift b/ios/Video/Features/RCTPictureInPicture.swift index 4525df0b..da6a9d8c 100644 --- a/ios/Video/Features/RCTPictureInPicture.swift +++ b/ios/Video/Features/RCTPictureInPicture.swift @@ -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 diff --git a/ios/Video/Features/RCTPlayerOperations.swift b/ios/Video/Features/RCTPlayerOperations.swift index 58bd35c2..f304edc8 100644 --- a/ios/Video/Features/RCTPlayerOperations.swift +++ b/ios/Video/Features/RCTPlayerOperations.swift @@ -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 diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 055a1915..43eec0e7 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -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 } }