fixing PIP mode on iOS
This commit is contained in:
parent
6b60428ec7
commit
35256062d9
@ -4,15 +4,15 @@ import MediaAccessibility
|
|||||||
import React
|
import React
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
#if TARGET_OS_IOS
|
#if os(iOS)
|
||||||
class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
|
class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
|
||||||
private var _onPictureInPictureStatusChanged: RCTDirectEventBlock?
|
private var _onPictureInPictureStatusChanged: (() -> Void)? = nil
|
||||||
private var _onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
|
private var _onRestoreUserInterfaceForPictureInPictureStop: (() -> Void)? = nil
|
||||||
private var _restoreUserInterfaceForPIPStopCompletionHandler:((Bool) -> Void)? = nil
|
private var _restoreUserInterfaceForPIPStopCompletionHandler:((Bool) -> Void)? = nil
|
||||||
private var _pipController:AVPictureInPictureController?
|
private var _pipController:AVPictureInPictureController?
|
||||||
private var _isActive:Bool = false
|
private var _isActive:Bool = false
|
||||||
|
|
||||||
init(_ onPictureInPictureStatusChanged: @escaping RCTDirectEventBlock, _ onRestoreUserInterfaceForPictureInPictureStop: @escaping RCTDirectEventBlock) {
|
init(_ onPictureInPictureStatusChanged: (() -> Void)? = nil, _ onRestoreUserInterfaceForPictureInPictureStop: (() -> Void)? = nil) {
|
||||||
_onPictureInPictureStatusChanged = onPictureInPictureStatusChanged
|
_onPictureInPictureStatusChanged = onPictureInPictureStatusChanged
|
||||||
_onRestoreUserInterfaceForPictureInPictureStop = onRestoreUserInterfaceForPictureInPictureStop
|
_onRestoreUserInterfaceForPictureInPictureStop = onRestoreUserInterfaceForPictureInPictureStop
|
||||||
}
|
}
|
||||||
@ -20,22 +20,20 @@ class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
|
|||||||
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
|
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
|
||||||
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
|
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
|
||||||
|
|
||||||
_onPictureInPictureStatusChanged([ "isActive": NSNumber(value: true)])
|
_onPictureInPictureStatusChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
|
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
|
||||||
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
|
guard let _onPictureInPictureStatusChanged = _onPictureInPictureStatusChanged else { return }
|
||||||
|
|
||||||
_onPictureInPictureStatusChanged([ "isActive": NSNumber(value: false)])
|
_onPictureInPictureStatusChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
|
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 }
|
guard let _onRestoreUserInterfaceForPictureInPictureStop = _onRestoreUserInterfaceForPictureInPictureStop else { return }
|
||||||
|
|
||||||
_onRestoreUserInterfaceForPictureInPictureStop([:])
|
_onRestoreUserInterfaceForPictureInPictureStop()
|
||||||
|
|
||||||
_restoreUserInterfaceForPIPStopCompletionHandler = completionHandler
|
_restoreUserInterfaceForPIPStopCompletionHandler = completionHandler
|
||||||
}
|
}
|
||||||
@ -47,7 +45,6 @@ class RCTPictureInPicture: NSObject, AVPictureInPictureControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupPipController(_ playerLayer: AVPlayerLayer?) {
|
func setupPipController(_ playerLayer: AVPlayerLayer?) {
|
||||||
guard playerLayer != nil && AVPictureInPictureController.isPictureInPictureSupported() && _isActive else { return }
|
|
||||||
// Create new controller passing reference to the AVPlayerLayer
|
// Create new controller passing reference to the AVPlayerLayer
|
||||||
_pipController = AVPictureInPictureController(playerLayer:playerLayer!)
|
_pipController = AVPictureInPictureController(playerLayer:playerLayer!)
|
||||||
_pipController?.delegate = self
|
_pipController?.delegate = self
|
||||||
|
@ -112,15 +112,13 @@ enum RCTPlayerOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // default. invalid type or "system"
|
} else { // default. invalid type or "system"
|
||||||
#if os(tvOS)
|
#if os(iOS)
|
||||||
// Do noting. Fix for tvOS native audio menu language selector
|
|
||||||
#else
|
|
||||||
player?.currentItem?.selectMediaOptionAutomatically(in: group)
|
player?.currentItem?.selectMediaOptionAutomatically(in: group)
|
||||||
return
|
return
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(tvOS)
|
#if os(iOS)
|
||||||
// Do noting. Fix for tvOS native audio menu language selector
|
// Do noting. Fix for tvOS native audio menu language selector
|
||||||
#else
|
#else
|
||||||
// If a match isn't found, option will be nil and text tracks will be disabled
|
// If a match isn't found, option will be nil and text tracks will be disabled
|
||||||
|
@ -81,8 +81,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
private let _videoCache:RCTVideoCachingHandler = RCTVideoCachingHandler()
|
private let _videoCache:RCTVideoCachingHandler = RCTVideoCachingHandler()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TARGET_OS_IOS
|
#if os(iOS)
|
||||||
private let _pip:RCTPictureInPicture = RCTPictureInPicture(self.onPictureInPictureStatusChanged, self.onRestoreUserInterfaceForPictureInPictureStop)
|
private var _pip:RCTPictureInPicture? = nil
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
@ -109,6 +109,14 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
@objc var onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
|
@objc var onRestoreUserInterfaceForPictureInPictureStop: RCTDirectEventBlock?
|
||||||
@objc var onGetLicense: RCTDirectEventBlock?
|
@objc var onGetLicense: RCTDirectEventBlock?
|
||||||
@objc var onReceiveAdEvent: RCTDirectEventBlock?
|
@objc var onReceiveAdEvent: RCTDirectEventBlock?
|
||||||
|
|
||||||
|
@objc func _onPictureInPictureStatusChanged() {
|
||||||
|
onPictureInPictureStatusChanged?([ "isActive": NSNumber(value: true)])
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func _onRestoreUserInterfaceForPictureInPictureStop() {
|
||||||
|
onPictureInPictureStatusChanged?([ "isActive": NSNumber(value: false)])
|
||||||
|
}
|
||||||
|
|
||||||
init(eventDispatcher:RCTEventDispatcher!) {
|
init(eventDispatcher:RCTEventDispatcher!) {
|
||||||
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
||||||
@ -118,6 +126,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
|
|
||||||
_eventDispatcher = eventDispatcher
|
_eventDispatcher = eventDispatcher
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
_pip = RCTPictureInPicture(self._onPictureInPictureStatusChanged, self._onRestoreUserInterfaceForPictureInPictureStop)
|
||||||
|
#endif
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
NotificationCenter.default.addObserver(
|
||||||
self,
|
self,
|
||||||
selector: #selector(applicationWillResignActive(notification:)),
|
selector: #selector(applicationWillResignActive(notification:)),
|
||||||
@ -410,15 +422,15 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
|
|
||||||
@objc
|
@objc
|
||||||
func setPictureInPicture(_ pictureInPicture:Bool) {
|
func setPictureInPicture(_ pictureInPicture:Bool) {
|
||||||
#if TARGET_OS_IOS
|
#if os(iOS)
|
||||||
_pip.setPictureInPicture(pictureInPicture)
|
_pip?.setPictureInPicture(pictureInPicture)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore:Bool) {
|
func setRestoreUserInterfaceForPIPStopCompletionHandler(_ restore:Bool) {
|
||||||
#if TARGET_OS_IOS
|
#if os(iOS)
|
||||||
_pip.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
_pip?.setRestoreUserInterfaceForPIPStopCompletionHandler(restore)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,6 +749,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
|
|
||||||
viewController.view.frame = self.bounds
|
viewController.view.frame = self.bounds
|
||||||
viewController.player = player
|
viewController.player = player
|
||||||
|
viewController.allowsPictureInPicturePlayback = true
|
||||||
return viewController
|
return viewController
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,8 +768,8 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
self.layer.addSublayer(_playerLayer)
|
self.layer.addSublayer(_playerLayer)
|
||||||
}
|
}
|
||||||
self.layer.needsDisplayOnBoundsChange = true
|
self.layer.needsDisplayOnBoundsChange = true
|
||||||
#if TARGET_OS_IOS
|
#if os(iOS)
|
||||||
_pip.setupPipController(_playerLayer)
|
_pip?.setupPipController(_playerLayer)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user