fix: entering PiP mode when controls are true (#4776)

This commit is contained in:
Kamil Moskała
2025-11-18 14:45:40 +01:00
committed by GitHub
parent fbb260e916
commit ba65ab1233

View File

@@ -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
}
}
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
}
}
for subview in view.subviews {
if let playerLayer = findPlayerLayer(in: subview) {
return playerLayer
}
}
return nil
}
@objc
func enterPictureInPicture() {
if _pip?._pipController == nil {
#if os(iOS)
if _pip == nil {
initPictureinPicture()
if #available(iOS 9.0, tvOS 14.0, *) {
_playerViewController?.allowsPictureInPicturePlayback = true
}
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
}
}
}