From a3422b0bdfb3134b4a79b938583fe234df743882 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Sat, 16 Aug 2025 23:54:21 +0200 Subject: [PATCH 01/11] feat(Android): add PIP resizeMode support --- .../exoplayer/PictureInPictureUtil.kt | 1 + .../exoplayer/ReactExoplayerView.java | 11 ++++++++++ .../exoplayer/ReactExoplayerViewManager.kt | 21 +++++++++++++++---- package.json | 4 +++- src/Video.tsx | 2 ++ src/specs/VideoNativeComponent.ts | 1 + src/types/video.ts | 1 + 7 files changed, 36 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/PictureInPictureUtil.kt b/android/src/main/java/com/brentvatne/exoplayer/PictureInPictureUtil.kt index 3e3088a245..1db7f4be6d 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/PictureInPictureUtil.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/PictureInPictureUtil.kt @@ -43,6 +43,7 @@ object PictureInPictureUtil { val onPictureInPictureModeChanged = Consumer { info -> view.setIsInPictureInPicture(info.isInPictureInPictureMode) + view.setPictureInPictureMode(info.isInPictureInPictureMode) if (!info.isInPictureInPictureMode && activity.lifecycle.currentState == Lifecycle.State.CREATED) { // when user click close button of PIP if (!view.playInBackground) view.setPausedModifier(true) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index bea60c0980..3faa2b7be1 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -246,6 +246,7 @@ public class ReactExoplayerView extends FrameLayout implements protected boolean playInBackground = false; private boolean mReportBandwidth = false; private boolean controls = false; + private int pictureInPictureResizeMode = -1; private boolean showNotificationControls = false; // \ End props @@ -2511,6 +2512,16 @@ public void exitPictureInPictureMode() { } } + public void setPictureInPictureResizeModeModifier(@ResizeMode.Mode int resizeMode) { + this.pictureInPictureResizeMode = resizeMode; + } + + public void setPictureInPictureMode(boolean isInPiP) { + if (exoPlayerView != null && isInPiP && pictureInPictureResizeMode != -1) { + exoPlayerView.setResizeMode(pictureInPictureResizeMode); + } + } + public void setMutedModifier(boolean muted) { this.muted = muted; if (player != null) { diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt index b9e065646b..8a5fa58eb0 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt @@ -58,6 +58,7 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View private const val PROP_SHOW_NOTIFICATION_CONTROLS = "showNotificationControls" private const val PROP_DEBUG = "debug" private const val PROP_CONTROLS_STYLES = "controlsStyles" + private const val PROP_PICTURE_IN_PICTURE_RESIZE_MODE = "pictureInPictureResizeMode" } override fun getName(): String = REACT_CLASS @@ -258,9 +259,21 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View videoView.setDebug(enableDebug) } - @ReactProp(name = PROP_CONTROLS_STYLES) - fun setControlsStyles(videoView: ReactExoplayerView, controlsStyles: ReadableMap?) { - val controlsConfig = ControlsConfig.parse(controlsStyles) - videoView.setControlsStyles(controlsConfig) + @ReactProp(name = PROP_PICTURE_IN_PICTURE_RESIZE_MODE) + fun setPictureInPictureResizeMode(videoView: ReactExoplayerView, resizeMode: String?) { + val mode = when (resizeMode) { + "none", "contain" -> ResizeMode.RESIZE_MODE_FIT + "cover" -> ResizeMode.RESIZE_MODE_CENTER_CROP + "stretch" -> ResizeMode.RESIZE_MODE_FILL + else -> { + if (resizeMode != null) { + DebugLog.w(TAG, "Unsupported PiP resize mode: $resizeMode - falling back to fit") + } + ResizeMode.RESIZE_MODE_FIT + } + } + + videoView.setPictureInPictureResizeModeModifier(mode) } + } diff --git a/package.json b/package.json index 26e11ab0d7..e570bb1e68 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@react-native/eslint-config": "^0.72.2", "@release-it/conventional-changelog": "^7.0.2", "@types/jest": "^28.1.2", + "@types/node": "^24.3.0", "@types/react": "~19.0.0", "@types/react-native-web": "^0.19.1", "@typescript-eslint/eslint-plugin": "^6.7.4", @@ -67,5 +68,6 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ] + ], + "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } diff --git a/src/Video.tsx b/src/Video.tsx index 6d39f24ae3..b20c2f4aa2 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -109,6 +109,7 @@ const Video = forwardRef( localSourceEncryptionKeyScheme, minLoadRetryCount, bufferConfig, + pictureInPictureResizeMode, ...rest }, ref, @@ -905,6 +906,7 @@ const Video = forwardRef( onControlsVisibilityChange ? _onControlsVisibilityChange : undefined } viewType={_viewType} + pictureInPictureResizeMode={pictureInPictureResizeMode} /> {_renderPoster()} diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index 493736d990..3a70ecce51 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -401,6 +401,7 @@ export interface VideoNativeProps extends ViewProps { onTextTracks?: DirectEventHandler; // android onTextTrackDataChanged?: DirectEventHandler; // iOS onVideoTracks?: DirectEventHandler; // android + pictureInPictureResizeMode?: WithDefault; } type NativeVideoComponentType = HostComponent; diff --git a/src/types/video.ts b/src/types/video.ts index 82861bd667..24fb68b251 100644 --- a/src/types/video.ts +++ b/src/types/video.ts @@ -351,4 +351,5 @@ export interface ReactVideoProps extends ReactVideoEvents, ViewProps { allowsExternalPlayback?: boolean; // iOS controlsStyles?: ControlsStyles; // Android disableAudioSessionManagement?: boolean; // iOS + pictureInPictureResizeMode?: EnumValues; // Android } From 431b0fec317832658428b8b509a4b009e5315b19 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Sun, 17 Aug 2025 00:02:41 +0200 Subject: [PATCH 02/11] re-add props controls style --- .../com/brentvatne/exoplayer/ReactExoplayerViewManager.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt index 8a5fa58eb0..194313f7ad 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt @@ -276,4 +276,10 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View videoView.setPictureInPictureResizeModeModifier(mode) } + @ReactProp(name = PROP_CONTROLS_STYLES) + fun setControlsStyles(videoView: ReactExoplayerView, controlsStyles: ReadableMap?) { + val controlsConfig = ControlsConfig.parse(controlsStyles) + videoView.setControlsStyles(controlsConfig) + } + } From 7e4b34545ea1f526f9a080c81df3065aed35881b Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Sun, 17 Aug 2025 00:44:30 +0200 Subject: [PATCH 03/11] Remove package manager --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index e570bb1e68..f763669f1c 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "@react-native/eslint-config": "^0.72.2", "@release-it/conventional-changelog": "^7.0.2", "@types/jest": "^28.1.2", - "@types/node": "^24.3.0", "@types/react": "~19.0.0", "@types/react-native-web": "^0.19.1", "@typescript-eslint/eslint-plugin": "^6.7.4", @@ -69,5 +68,4 @@ "!docs", "!examples" ], - "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } From 2fa6a73877653817124addc26ddaa543107e5b9d Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Sun, 17 Aug 2025 00:51:49 +0200 Subject: [PATCH 04/11] feat(Android): add PIP resizeMode support --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f763669f1c..26e11ab0d7 100644 --- a/package.json +++ b/package.json @@ -67,5 +67,5 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ], + ] } From 7b9d8cd1bb977f4af21747d0c403d49d58b3d615 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:51:55 +0200 Subject: [PATCH 05/11] lint project --- package.json | 20 +++++++++++++++----- src/types/video.ts | 4 ++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 26e11ab0d7..993991ab1a 100644 --- a/package.json +++ b/package.json @@ -15,17 +15,26 @@ "devDependencies": { "@expo/config-plugins": "^8.0.5", "@jamesacarr/eslint-formatter-github-actions": "^0.2.0", - "@react-native/eslint-config": "^0.72.2", + "@react-native/eslint-config": "0.81.1", + "@react-native/eslint-plugin": "0.81.1", "@release-it/conventional-changelog": "^7.0.2", "@types/jest": "^28.1.2", "@types/react": "~19.0.0", "@types/react-native-web": "^0.19.1", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "eslint": "^8.19.0", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", + "eslint": "^8", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-ft-flow": "^3.0.11", "eslint-plugin-jest": "^27.4.2", + "eslint-plugin-prettier": "^5.5.4", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-native": "^5.0.0", "husky": "^9.1.7", "jest": "^29.7.0", - "prettier": "^2.4.1", + "prettier": "^3.6.2", "react": "18.2.0", "react-native": "0.78.2", "react-native-web": "0.20.0", @@ -67,5 +76,6 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ] + ], + "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } diff --git a/src/types/video.ts b/src/types/video.ts index 24fb68b251..d889d57ec3 100644 --- a/src/types/video.ts +++ b/src/types/video.ts @@ -91,14 +91,14 @@ export type Drm = Readonly<{ base64Certificate?: boolean; // ios default: false multiDrm?: boolean; // android localSourceEncryptionKeyScheme?: string; // ios - /* eslint-disable @typescript-eslint/no-unused-vars */ + getLicense?: ( spcBase64: string, contentId: string, licenseUrl: string, loadedLicenseUrl: string, ) => string | Promise; // ios - /* eslint-enable @typescript-eslint/no-unused-vars */ + }>; export enum CmcdMode { From d51e7147d521dbdcd11bb758644cf700a2f33cd0 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:59:30 +0200 Subject: [PATCH 06/11] Fix: package.json miss --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 993991ab1a..f5ac59155b 100644 --- a/package.json +++ b/package.json @@ -77,5 +77,4 @@ "!docs", "!examples" ], - "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } From 08a4386b49e5a79ea4cc8092706528a5dce2fc51 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:01:07 +0200 Subject: [PATCH 07/11] Fix: package.json miss --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f5ac59155b..b51be1f560 100644 --- a/package.json +++ b/package.json @@ -76,5 +76,5 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ], + ] } From 6ef618520bc580b72fd93a54e6101a16bc60e2da Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 16:49:38 +0200 Subject: [PATCH 08/11] Fix: ktlint --- .../com/brentvatne/exoplayer/ReactExoplayerViewManager.kt | 1 - package.json | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt index 194313f7ad..6b0f68aa71 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.kt @@ -281,5 +281,4 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View val controlsConfig = ControlsConfig.parse(controlsStyles) videoView.setControlsStyles(controlsConfig) } - } diff --git a/package.json b/package.json index b51be1f560..afd886ef7c 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "eslint-plugin-react-native": "^5.0.0", "husky": "^9.1.7", "jest": "^29.7.0", + "ktlint": "^0.0.5", "prettier": "^3.6.2", "react": "18.2.0", "react-native": "0.78.2", @@ -76,5 +77,6 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ] + ], + "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } From 74bd47b5e1e9f31db6c88b26249feb243c7c9373 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 16:49:56 +0200 Subject: [PATCH 09/11] Fix: ktlint --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index afd886ef7c..d8a5a6a27e 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,5 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ], - "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" + ] } From 0027b68ceee1b5404e707e24589557974410f724 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 21:29:04 +0200 Subject: [PATCH 10/11] Fix: exit pip video size properly --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 6 ++++++ .../src/main/java/com/anonymous/ExpoExample/MainActivity.kt | 2 +- .../main/java/com/anonymous/ExpoExample/MainApplication.kt | 2 +- .../expo/android/react-settings-plugin/build.gradle.kts | 2 +- .../java/com/videopluginsample/VideoPluginSampleModule.kt | 1 - package.json | 3 ++- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 3faa2b7be1..eefb1ec3f2 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -2476,6 +2476,12 @@ protected void setIsInPictureInPicture(boolean isInPictureInPicture) { } addView(exoPlayerView, 0, layoutParams); } + if (exoPlayerView != null) { + exoPlayerView.post(() -> { + exoPlayerView.requestLayout(); + reLayout(exoPlayerView); + }); + } } } diff --git a/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainActivity.kt b/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainActivity.kt index 519d0475e5..0d4147e7bf 100644 --- a/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainActivity.kt +++ b/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainActivity.kt @@ -41,7 +41,7 @@ class MainActivity : ReactActivity() { this, mainComponentName, fabricEnabled - ){}) + ) {}) } /** diff --git a/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainApplication.kt b/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainApplication.kt index 2bb577e0c4..e102e0d4a0 100644 --- a/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainApplication.kt +++ b/examples/expo/android/app/src/main/java/com/anonymous/ExpoExample/MainApplication.kt @@ -25,7 +25,7 @@ class MainApplication : Application(), ReactApplication { override fun getPackages(): List { // Packages that cannot be autolinked yet can be added manually here, for example: var packages = PackageList(this).packages - packages.add(ReactVideoPackage()); + packages.add(ReactVideoPackage()) return packages } diff --git a/examples/expo/android/react-settings-plugin/build.gradle.kts b/examples/expo/android/react-settings-plugin/build.gradle.kts index b4f6668e9e..ac56ca8614 100644 --- a/examples/expo/android/react-settings-plugin/build.gradle.kts +++ b/examples/expo/android/react-settings-plugin/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { kotlin("jvm") version "1.9.24" diff --git a/examples/react-native-video-plugin-sample/android/src/main/java/com/videopluginsample/VideoPluginSampleModule.kt b/examples/react-native-video-plugin-sample/android/src/main/java/com/videopluginsample/VideoPluginSampleModule.kt index bba2449d0a..9d94d88fd7 100644 --- a/examples/react-native-video-plugin-sample/android/src/main/java/com/videopluginsample/VideoPluginSampleModule.kt +++ b/examples/react-native-video-plugin-sample/android/src/main/java/com/videopluginsample/VideoPluginSampleModule.kt @@ -34,7 +34,6 @@ class VideoPluginSampleModule(reactContext: ReactApplicationContext) : DebugLog.e(TAG, "onPlayerError: " + error.errorCodeName) } - override fun onInstanceCreated(id: String, player: ExoPlayer) { player.addAnalyticsListener(debugEventLogger) player.addListener(this) diff --git a/package.json b/package.json index d8a5a6a27e..afd886ef7c 100644 --- a/package.json +++ b/package.json @@ -77,5 +77,6 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ] + ], + "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" } From 0f9b4c763ede5b8452be0f70fcf3bc6dbbac9794 Mon Sep 17 00:00:00 2001 From: Zakaria <101876655+Zakariasma@users.noreply.github.com> Date: Fri, 12 Sep 2025 21:54:33 +0200 Subject: [PATCH 11/11] Ts lint + remove package --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index afd886ef7c..d8a5a6a27e 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,5 @@ "!**/*.tsbuildinfo", "!docs", "!examples" - ], - "packageManager": "yarn@4.1.1+sha512.ec40d0639bb307441b945d9467139cbb88d14394baac760b52eca038b330d16542d66fef61574271534ace5a200518dabf3b53a85f1f9e4bfa37141b538a9590" + ] }