diff --git a/examples/basic/index.js b/examples/basic/index.js new file mode 100644 index 00000000..cbc5a71f --- /dev/null +++ b/examples/basic/index.js @@ -0,0 +1,2 @@ +// Without this file, the example will not build on physical devices +import './src/index'; diff --git a/examples/basic/ios/Podfile.lock b/examples/basic/ios/Podfile.lock index c54c33e9..8d2f45c9 100644 --- a/examples/basic/ios/Podfile.lock +++ b/examples/basic/ios/Podfile.lock @@ -935,11 +935,49 @@ PODS: - React-Mapbuffer (0.74.0-rc.4): - glog - React-debug - - react-native-video (6.0.0-beta.6): + - react-native-video (6.0.0-beta.8): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen - React-Core - - react-native-video/Video (= 6.0.0-beta.6) - - react-native-video/Video (6.0.0-beta.6): + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - react-native-video/Video (= 6.0.0-beta.8) + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - react-native-video/Video (6.0.0-beta.8): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - React-nativeconfig (0.74.0-rc.4) - React-NativeModulesApple (0.74.0-rc.4): - glog @@ -1383,7 +1421,7 @@ SPEC CHECKSUMS: React-jsitracing: 50e3ea936a199a2a7fcab922f156507c97f0b88c React-logger: 6004e0cf41b7e9714ca26b1648e5d76fcfd638b5 React-Mapbuffer: 9b163fa28e549d5f36f89a39a1145fcaf262d0d0 - react-native-video: d340c162bf7974c2935fbeec0c5dea362f9dd74a + react-native-video: 64df5d2bc3bbc028cb97d87b53e42583127a9b9e React-nativeconfig: 3948d6fb6acfec364625cffbb1cf420346fb37c0 React-NativeModulesApple: 46745aba687c1019983d56b6d5fa39265152f64f React-perflogger: 0d62c0261b6fd3920605850de91abc8135dd3ee9 diff --git a/ios/Video/Features/RCTPictureInPicture.swift b/ios/Video/Features/RCTPictureInPicture.swift index 6f5ef79e..0d745d7c 100644 --- a/ios/Video/Features/RCTPictureInPicture.swift +++ b/ios/Video/Features/RCTPictureInPicture.swift @@ -63,6 +63,10 @@ import React _pipController?.delegate = self } + func deinitPipController() { + _pipController = nil + } + func setPictureInPicture(_ isActive: Bool) { if _isActive == isActive { return diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index 571cc8c0..fb6e9b96 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -64,8 +64,20 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH private var _filterName: String! private var _filterEnabled = false private var _presentingViewController: UIViewController? - private var _pictureInPictureEnabled = false private var _startPosition: Float64 = -1 + private var _pictureInPictureEnabled = false { + didSet { + #if os(iOS) + if _pictureInPictureEnabled { + initPictureinPicture() + _playerViewController?.allowsPictureInPicturePlayback = true + } else { + _pip?.deinitPipController() + _playerViewController?.allowsPictureInPicturePlayback = false + } + #endif + } + } /* IMA Ads */ private var _adTagUrl: String? @@ -144,6 +156,24 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH return _pictureInPictureEnabled } + func initPictureinPicture() { + #if os(iOS) + _pip = RCTPictureInPicture({ [weak self] in + self?._onPictureInPictureEnter() + }, { [weak self] in + self?._onPictureInPictureExit() + }, { [weak self] in + self?.onRestoreUserInterfaceForPictureInPictureStop?([:]) + }) + + if _playerLayer != nil && !_controls { + _pip?.setupPipController(_playerLayer) + } + #else + DebugLog("Picture in Picture is not supported on this platform") + #endif + } + init(eventDispatcher: RCTEventDispatcher!) { super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) #if USE_GOOGLE_IMA @@ -153,13 +183,12 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH _eventDispatcher = eventDispatcher #if os(iOS) - _pip = RCTPictureInPicture({ [weak self] in - self?._onPictureInPictureEnter() - }, { [weak self] in - self?._onPictureInPictureExit() - }, { [weak self] in - self?.onRestoreUserInterfaceForPictureInPictureStop?([:]) - }) + if _pictureInPictureEnabled { + initPictureinPicture() + _playerViewController?.allowsPictureInPicturePlayback = true + } else { + _playerViewController?.allowsPictureInPicturePlayback = false + } #endif NotificationCenter.default.addObserver( @@ -970,7 +999,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH viewController.view.frame = self.bounds viewController.player = player if #available(tvOS 14.0, *) { - viewController.allowsPictureInPicturePlayback = true + viewController.allowsPictureInPicturePlayback = _pictureInPictureEnabled } return viewController } @@ -991,7 +1020,9 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } self.layer.needsDisplayOnBoundsChange = true #if os(iOS) - _pip?.setupPipController(_playerLayer) + if _pictureInPictureEnabled { + _pip?.setupPipController(_playerLayer) + } #endif } }