diff --git a/ios/Video/RCTVideo.swift b/ios/Video/RCTVideo.swift index b8cd390d..e7cf35f9 100644 --- a/ios/Video/RCTVideo.swift +++ b/ios/Video/RCTVideo.swift @@ -68,14 +68,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH if isPictureInPictureActive() { return } if _enterPictureInPictureOnLeave { initPictureinPicture() - if #available(iOS 9.0, tvOS 14.0, *) { - _playerViewController?.allowsPictureInPicturePlayback = true - } } else { _pip?.deinitPipController() - if #available(iOS 9.0, tvOS 14.0, *) { - _playerViewController?.allowsPictureInPicturePlayback = false - } } } } @@ -105,6 +99,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH #endif private var _pip: RCTPictureInPicture? + private var _isPictureInPictureActive = false // Events @objc var onVideoLoadStart: RCTDirectEventBlock? @@ -138,19 +133,21 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH @objc func _onPictureInPictureEnter() { - onPictureInPictureStatusChanged?(["isActive": NSNumber(value: true)]) + handlePictureInPictureEnter() } @objc func _onPictureInPictureExit() { - onPictureInPictureStatusChanged?(["isActive": NSNumber(value: false)]) + handlePictureInPictureExit() } func handlePictureInPictureEnter() { + _isPictureInPictureActive = true onPictureInPictureStatusChanged?(["isActive": NSNumber(value: true)]) } func handlePictureInPictureExit() { + _isPictureInPictureActive = false onPictureInPictureStatusChanged?(["isActive": NSNumber(value: false)]) // To continue audio playback in backgroud we need to set @@ -169,7 +166,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH func isPictureInPictureActive() -> Bool { #if os(iOS) - return _pip?._pipController?.isPictureInPictureActive == true + return _isPictureInPictureActive #else return false #endif @@ -1211,9 +1208,6 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } } - if #available(iOS 9.0, tvOS 14.0, *) { - viewController.allowsPictureInPicturePlayback = _enterPictureInPictureOnLeave - } return viewController } @@ -1244,6 +1238,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH func setControls(_ controls: Bool) { if _controls != controls || ((_playerLayer == nil) && (_playerViewController == nil)) { _controls = controls + #if os(iOS) + if !isPictureInPictureActive() { + _pip?.deinitPipController() + } + #endif if _controls { DispatchQueue.main.async { self.removePlayerLayer() @@ -1828,15 +1827,38 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH } } - @objc - func enterPictureInPicture() { - if _pip?._pipController == nil { - initPictureinPicture() - if #available(iOS 9.0, tvOS 14.0, *) { - _playerViewController?.allowsPictureInPicturePlayback = true + private func findPlayerLayer(in view: UIView) -> AVPlayerLayer? { + if let layer = view.layer as? AVPlayerLayer { + return layer + } + for sublayer in view.layer.sublayers ?? [] { + if let playerLayer = sublayer as? AVPlayerLayer { + return playerLayer } } - _pip?.enterPictureInPicture() + for subview in view.subviews { + if let playerLayer = findPlayerLayer(in: subview) { + return playerLayer + } + } + return nil + } + + @objc + func enterPictureInPicture() { + #if os(iOS) + if _pip == nil { + initPictureinPicture() + } + + if _pip?._pipController == nil, let playerViewController = _playerViewController, _controls { + if let existingPlayerLayer = findPlayerLayer(in: playerViewController.view) { + _pip?.setupPipController(existingPlayerLayer) + } + } + + _pip?.enterPictureInPicture() + #endif } @objc @@ -1846,14 +1868,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH _pip?.exitPictureInPicture() if _enterPictureInPictureOnLeave { initPictureinPicture() - if #available(iOS 9.0, tvOS 14.0, *) { - _playerViewController?.allowsPictureInPicturePlayback = true - } } else { _pip?.deinitPipController() - if #available(iOS 9.0, tvOS 14.0, *) { - _playerViewController?.allowsPictureInPicturePlayback = false - } } }