feat: implement enterPictureInPictureOnLeave prop for both platform (Android, iOS) (#3385)
* docs: enable Android PIP * chore: change comments * feat(android): implement Android PictureInPicture * refactor: minor refactor code and apply lint * fix: rewrite pip action intent code for Android14 * fix: remove redundant codes * feat: add isInPictureInPicture flag for lifecycle handling - activity provide helper method for same purpose, but this flag makes code simple * feat: add pipFullscreenPlayerView for makes PIP include video only * fix: add manifest value checker for prevent crash * docs: add pictureInPicture prop's Android guide * fix: sync controller visibility * refactor: refining variable name * fix: check multi window mode when host pause - some OS version call onPause on multi-window mode * fix: handling when onStop is called while in multi-window mode * refactor: enhance PIP util codes * fix: fix FullscreenPlayerView constructor * refactor: add enterPictureInPictureOnLeave prop and pip methods - remove pictureInPicture boolean prop - add enterPictureInPictureOnLeave boolean prop - add enterPictureInPicture method - add exitPictureInPicture method * fix: fix lint error * fix: prevent audio play in background without playInBackground prop * fix: fix onDetachedFromWindow * docs: update docs for pip * fix(android): sync pip controller with external controller state - for media session * fix(ios): fix pip active fn variable reference * refactor(ios): refactor code * refactor(android): refactor codes * fix(android): fix lint error * refactor(android): refactor android pip logics * fix(android): fix flickering issue when stop picture in picture * fix(android): fix import * fix(android): fix picture in picture with fullscreen mode * fix(ios): fix syntax error * fix(android): fix Fragment managed code * refactor(android): remove redundant override lifecycle * fix(js): add PIP type definition for codegen * fix(android): fix syntax * chore(android): fix lint error * fix(ios): fix enter background handler * refactor(ios): remove redundant code * fix(ios): fix applicationDidEnterBackground for PIP * fix(android): fix onPictureInPictureStatusChanged * fix(ios): fix RCTPictureInPicture * refactor(android): Ignore exception for some device ignore pip checker - some device ignore PIP availability check, so we need to handle exception to prevent crash * fix(android): add hideWithoutPlayer fn into Kotlin ver * refactor(android): remove redundant code * fix(android): fix pip ratio to be calculated with correct ratio value * fix(android): fix crash issue when unmounting in PIP mode * fix(android): fix lint error * Update android/src/main/java/com/brentvatne/react/VideoManagerModule.kt * fix(android): fix lint error * fix(ios): fix lint error * fix(ios): fix lint error * feat(expo): add android picture in picture config within expo plugin * fix: Replace Fragment with androidx.activity - remove code that uses Fragment, which is a tricky implementation * fix: fix lint error * fix(android): disable auto enter when player released * fix(android): fix event handler to check based on Activity it's bound to --------- Co-authored-by: jonghun <jonghun@toss.im> Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com>
This commit is contained in:
@@ -4,16 +4,16 @@
|
||||
|
||||
class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate, IMALinkOpenerDelegate {
|
||||
private weak var _video: RCTVideo?
|
||||
private var _pipEnabled: () -> Bool
|
||||
private var _isPictureInPictureActive: () -> Bool
|
||||
|
||||
/* Entry point for the SDK. Used to make ad requests. */
|
||||
private var adsLoader: IMAAdsLoader!
|
||||
/* Main point of interaction with the SDK. Created by the SDK as the result of an ad request. */
|
||||
private var adsManager: IMAAdsManager!
|
||||
|
||||
init(video: RCTVideo!, pipEnabled: @escaping () -> Bool) {
|
||||
init(video: RCTVideo!, isPictureInPictureActive: @escaping () -> Bool) {
|
||||
_video = video
|
||||
_pipEnabled = pipEnabled
|
||||
_isPictureInPictureActive = isPictureInPictureActive
|
||||
|
||||
super.init()
|
||||
}
|
||||
@@ -103,7 +103,7 @@
|
||||
}
|
||||
// Play each ad once it has been loaded
|
||||
if event.type == IMAAdEventType.LOADED {
|
||||
if _pipEnabled() {
|
||||
if _isPictureInPictureActive() {
|
||||
return
|
||||
}
|
||||
adsManager.start()
|
||||
|
@@ -11,7 +11,9 @@ import React
|
||||
private var _onPictureInPictureExit: (() -> Void)?
|
||||
private var _onRestoreUserInterfaceForPictureInPictureStop: (() -> Void)?
|
||||
private var _restoreUserInterfaceForPIPStopCompletionHandler: ((Bool) -> Void)?
|
||||
private var _isActive = false
|
||||
private var _isPictureInPictureActive: Bool {
|
||||
return _pipController?.isPictureInPictureActive ?? false
|
||||
}
|
||||
|
||||
init(
|
||||
_ onPictureInPictureEnter: (() -> Void)? = nil,
|
||||
@@ -67,20 +69,22 @@ import React
|
||||
_pipController = nil
|
||||
}
|
||||
|
||||
func setPictureInPicture(_ isActive: Bool) {
|
||||
if _isActive == isActive {
|
||||
return
|
||||
}
|
||||
_isActive = isActive
|
||||
|
||||
func enterPictureInPicture() {
|
||||
guard let _pipController else { return }
|
||||
if !_isPictureInPictureActive {
|
||||
_pipController.startPictureInPicture()
|
||||
}
|
||||
}
|
||||
|
||||
if _isActive && !_pipController.isPictureInPictureActive {
|
||||
DispatchQueue.main.async {
|
||||
_pipController.startPictureInPicture()
|
||||
}
|
||||
} else if !_isActive && _pipController.isPictureInPictureActive {
|
||||
DispatchQueue.main.async {
|
||||
func exitPictureInPicture() {
|
||||
guard let _pipController else { return }
|
||||
if _isPictureInPictureActive {
|
||||
let state = UIApplication.shared.applicationState
|
||||
if state == .background || state == .inactive {
|
||||
deinitPipController()
|
||||
_onPictureInPictureExit?()
|
||||
_onRestoreUserInterfaceForPictureInPictureStop?()
|
||||
} else {
|
||||
_pipController.stopPictureInPicture()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user