-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement enterPictureInPictureOnLeave prop for both platform(Android, iOS) #3385
base: master
Are you sure you want to change the base?
Conversation
Thank you for the PR, can you open a PR in draft, it will allow to comment on it. public void onHostPause() { |
I don't understand why you use a dedicated fragment : ReactExoplayerFragment can you explain why you had to use it please ? (point to doc or other sample is enough) |
can you enable pip in sample to be able to test easily please |
<Video
style={{width: '100%', height: 300, backgroundColor: 'black'}}
resizeMode={ResizeMode.CONTAIN}
source={{
uri: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel-en.ism/.mpd',
}}
selectedTextTrack={{
type: SelectedTrackType.INDEX,
value: 0,
}}
fullscreen={false}
controls
pictureInPicture
playWhenInactive
playInBackground={false}
debug={{enable: true, thread: true}}
onPictureInPictureStatusChanged={({isActive}) => {
console.log(isActive, 'isActive');
}}
/> |
To implement PIP, we need to use the |
Ok, but will it work without native controls ? |
Yes, it's same like iOS and there are no restrictions. |
I'm not sure, but as I know |
@nick-mccomb-easygo |
- activity provide helper method for same purpose, but this flag makes code simple
Hi. I'd like to let you know this PR is ready for review 🙌 FYI, I think this code is too mush complicate to understand. |
android/src/main/java/com/brentvatne/exoplayer/PictureInPictureUtil.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍, thank you for the PR!
Tested it on Android 14, and 10 (simulators) and it worked for me. Will test it on device later.
Lets @freeboub review and for me we can merge
4621774
to
1b3a0b2
Compare
I just fix conflict. The only comments I have are in the discussion |
I have created |
I have released next rc version 6.8.0-rc.0 - if there will be no reported issues, this PR should be merged 🙌 |
Hi @YangJonghun, I'm encountering the same issue as @tiplefbxx mentioned where my app would always crash upon return from PIP. For a little bit more context, I have a separated Video component outside my navigator stack, and in my testing unload the video component below when having a floating player eliminates this behavior. Your app just crashed. See the error below.
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
java.util.ArrayList.get(ArrayList.java:437)
com.brentvatne.exoplayer.ReactExoplayerView.setIsInPictureInPicture(ReactExoplayerView.java:2305)
com.brentvatne.exoplayer.ReactExoplayerFragment.onPictureInPictureModeChanged(ReactExoplayerFragment.kt:35)
androidx.fragment.app.Fragment.performPictureInPictureModeChanged(Fragment.java:3221)
androidx.fragment.app.FragmentManager.dispatchPictureInPictureModeChanged(FragmentManager.java:3017)
androidx.fragment.app.FragmentManager.lambda$new$3$androidx-fragment-app-FragmentManager(FragmentManager.java:468)
androidx.fragment.app.FragmentManager$$ExternalSyntheticLambda3.accept(Unknown Source:4)
androidx.activity.ComponentActivity.onPictureInPictureModeChanged(ComponentActivity.java:1097)
android.app.Activity.dispatchPictureInPictureModeChanged(Unknown Source:23)
android.app.ActivityThread.handleWindowingModeChangeIfNeeded(Unknown Source:40)
android.app.ActivityThread.performActivityConfigurationChanged(Unknown Source:12)
android.app.ActivityThread.performConfigurationChangedForActivity(Unknown Source:28)
android.app.ActivityThread.handleActivityConfigurationChanged(Unknown Source:273)
android.app.ActivityThread$ActivityClientRecord$1.onConfigurationChanged(Unknown Source:14)
android.view.ViewRootImpl.performConfigurationChange(Unknown Source:81)
android.view.ViewRootImpl.handleResized(Unknown Source:112)
android.view.ViewRootImpl.-$$Nest$mhandleResized(Unknown Source:0)
android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl(Unknown Source:658)
android.view.ViewRootImpl$ViewRootHandler.handleMessage(Unknown Source:15)
android.os.Handler.dispatchMessage(Unknown Source:19)
android.os.Looper.loopOnce(Unknown Source:182)
android.os.Looper.loop(Unknown Source:82)
android.app.ActivityThread.main(Unknown Source:123)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
com.android.internal.os.ZygoteInit.main(Unknown Source:312) |
@tungmin97 |
@YangJonghun here is the crash example. I've found some issues only happen on android. 1 - We can still swipe home to enter pip even after the video outside navigation is paused, the other has 2 - Has both video playing, 3 - Resume the app while in PIP will always crash the application |
@tungmin97 FYI. @KrzysztofMoch @freeboub |
@l2hyunwoo May I request your code review?🙏 |
Hey @YangJonghun what is status of PR? Together with @freeboub we are okay to merge this PR - so let me know if you are also okay to merge it |
- remove code that uses Fragment, which is a tricky implementation
@KrzysztofMoch @freeboub
I'm fine with this PR being merged, but there are things that need to be fixed, so it would be nice to let the developers know that this is an experimental feature. |
|
||
val onPictureInPictureModeChanged: (info: PictureInPictureModeChangedInfo) -> Unit = { info: PictureInPictureModeChangedInfo -> | ||
view.setIsInPictureInPicture(info.isInPictureInPictureMode) | ||
if (!info.isInPictureInPictureMode && context.findActivity().lifecycle.currentState == Lifecycle.State.CREATED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!info.isInPictureInPictureMode && context.findActivity().lifecycle.currentState == Lifecycle.State.CREATED) { | |
if (!info.isInPictureInPictureMode && activity.lifecycle.currentState == Lifecycle.State.CREATED) { |
How about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it possible Activity is different between when bind eventListeners and when onPictureInPictureModeChanged
is called?🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes more sense to fix it as you said! We need to only handle Activity where the Video is visible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5e244e8
I've fixed it in above commit :)
Sure! We can go with what we have, I will open tickets for those issues |
So @YangJonghun, once you are ready please let me know 🙌 |
Update the changelog
feat(android): implement pictureInPicture prop and onPictureInPictureStatusChanged event
Describe the changes
(Breaking Change) Remove
pictureInPicture
boolean prop (iOS)Add
enterPictureInPictureOnLeave
boolean prop (Android, iOS)Add
enterPictureInPicture
method (Android, iOS)Add
exitPictureInPicture
method (Android, iOS)Add
onPictureInPictureStatusChanged
event listener (Android)Resolve issue React Native Video Picture In Picture for Android #2621
memo)
As I know Activity's
onUserLeaveHint
is acceptable lifecycle method for enter PIP. but it's impossible to detect that method within this library. so, I implemententerPicturInPicture
within onHostPause.If someone doesn't like this approach, please leave comment in this PR, I'll give you intent style code.