From 2a4dc1b00b792eaa114d018ee79de728a16b4ff1 Mon Sep 17 00:00:00 2001 From: Ash Mishra Date: Tue, 18 Jun 2024 11:48:09 -0700 Subject: [PATCH 1/5] Adding onControlsVisiblityChange for Android --- .../common/react/VideoEventEmitter.java | 11 +++++++++ .../exoplayer/ReactExoplayerView.java | 6 +++++ docs/pages/component/events.mdx | 20 ++++++++++++++++ src/Video.tsx | 24 +++++++++++++------ src/specs/VideoNativeComponent.ts | 5 ++++ src/types/events.ts | 2 ++ 6 files changed, 61 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.java b/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.java index 0f163b2525..be6166b46f 100644 --- a/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.java +++ b/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.java @@ -37,6 +37,7 @@ public VideoEventEmitter(ReactContext reactContext) { private static final String EVENT_ERROR = "onVideoError"; private static final String EVENT_PROGRESS = "onVideoProgress"; private static final String EVENT_BANDWIDTH = "onVideoBandwidthUpdate"; + private static final String EVENT_CONTROLS_VISIBILITY_CHANGE = "onControlsVisibilityChange"; private static final String EVENT_SEEK = "onVideoSeek"; private static final String EVENT_END = "onVideoEnd"; private static final String EVENT_FULLSCREEN_WILL_PRESENT = "onVideoFullscreenPlayerWillPresent"; @@ -89,6 +90,7 @@ public VideoEventEmitter(ReactContext reactContext) { EVENT_TEXT_TRACK_DATA_CHANGED, EVENT_VIDEO_TRACKS, EVENT_BANDWIDTH, + EVENT_CONTROLS_VISIBILITY_CHANGE, EVENT_ON_RECEIVE_AD_EVENT }; @@ -120,6 +122,7 @@ public VideoEventEmitter(ReactContext reactContext) { EVENT_TEXT_TRACK_DATA_CHANGED, EVENT_VIDEO_TRACKS, EVENT_BANDWIDTH, + EVENT_CONTROLS_VISIBILITY_CHANGE, EVENT_ON_RECEIVE_AD_EVENT }) @interface VideoEvents { @@ -164,6 +167,8 @@ public VideoEventEmitter(ReactContext reactContext) { private static final String EVENT_PROP_IS_PLAYING = "isPlaying"; + private static final String EVENT_CONTROLS_VISIBLE = "isVisible"; + public void setViewId(int viewId) { this.viewId = viewId; } @@ -354,6 +359,12 @@ public void end() { receiveEvent(EVENT_END, null); } + public void controlsVisibilityChanged(boolean isVisible) { + WritableMap map = Arguments.createMap(); + map.putBoolean(EVENT_CONTROLS_VISIBLE, isVisible); + receiveEvent(EVENT_CONTROLS_VISIBILITY_CHANGE, map); + } + public void fullscreenWillPresent() { receiveEvent(EVENT_FULLSCREEN_WILL_PRESENT, null); } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index b306dcf3d4..79b3bbee99 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -416,6 +416,12 @@ private void togglePlayerControlVisibility() { private void initializePlayerControl() { if (playerControlView == null) { playerControlView = new LegacyPlayerControlView(getContext()); + playerControlView.addVisibilityListener(new LegacyPlayerControlView.VisibilityListener() { + @Override + public void onVisibilityChange(int visibility) { + eventEmitter.controlsVisibilityChanged(visibility == View.VISIBLE); + } + }); } if (fullScreenPlayerView == null) { diff --git a/docs/pages/component/events.mdx b/docs/pages/component/events.mdx index 713547571f..146c0d65d5 100644 --- a/docs/pages/component/events.mdx +++ b/docs/pages/component/events.mdx @@ -121,6 +121,26 @@ Example: } ``` +### `onControlsVisibilityChange` + + + +Callback function that is called when the controls are hidden or shown. Not possible on iOS. + +Payload: + +| Property | Type | Description | +| ----------- | ------- | ---------------------------------------------- | +| isVisible | boolean | Boolean indicating whether controls are visible | + +Example: + +```javascript +{ + isVisible: true; +} +``` + ### `onEnd` diff --git a/src/Video.tsx b/src/Video.tsx index 05c5c08374..71f2cd32fa 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -22,6 +22,7 @@ import NativeVideoComponent, { type OnAudioTracksData, type OnBandwidthUpdateData, type OnBufferData, + type OnControlsVisibilityChange, type OnExternalPlaybackChangeData, type OnGetLicenseData, type OnLoadStartData, @@ -91,6 +92,7 @@ const Video = forwardRef( onEnd, onBuffer, onBandwidthUpdate, + onControlsVisibilityChange, onExternalPlaybackChange, onFullscreenPlayerWillPresent, onFullscreenPlayerDidPresent, @@ -391,13 +393,6 @@ const Video = forwardRef( [onVideoTracks], ); - const _onPlaybackRateChange = useCallback( - (e: NativeSyntheticEvent>) => { - onPlaybackRateChange?.(e.nativeEvent); - }, - [onPlaybackRateChange], - ); - const _onVolumeChange = useCallback( (e: NativeSyntheticEvent>) => { onVolumeChange?.(e.nativeEvent); @@ -459,6 +454,20 @@ const Video = forwardRef( [onAspectRatio], ); + const _onPlaybackRateChange = useCallback( + (e: NativeSyntheticEvent>) => { + onPlaybackRateChange?.(e.nativeEvent); + }, + [onPlaybackRateChange], + ); + + const _onControlsVisibilityChange = useCallback( + (e: NativeSyntheticEvent) => { + onControlsVisibilityChange?.(e.nativeEvent); + }, + [onControlsVisibilityChange], + ) + const useExternalGetLicense = drm?.getLicense instanceof Function; const onGetLicense = useCallback( @@ -616,6 +625,7 @@ const Video = forwardRef( ? (_onReceiveAdEvent as (e: NativeSyntheticEvent) => void) : undefined } + onControlsVisibilityChange={onControlsVisibilityChange ? _onControlsVisibilityChange : undefined} /> {hasPoster && showPoster ? ( diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index f6e8ee6f48..a64dbb73c6 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -289,6 +289,10 @@ type ControlsStyles = Readonly<{ seekIncrementMS?: number; }>; +export type OnControlsVisibilityChange = Readonly<{ + isVisible: boolean; +}>; + export interface VideoNativeProps extends ViewProps { src?: VideoSrc; drm?: Drm; @@ -337,6 +341,7 @@ export interface VideoNativeProps extends ViewProps { useSecureView?: boolean; // Android bufferingStrategy?: BufferingStrategyType; // Android controlsStyles?: ControlsStyles; // Android + onControlsVisibilityChange?: DirectEventHandler; onVideoLoad?: DirectEventHandler; onVideoLoadStart?: DirectEventHandler; onVideoAspectRatio?: DirectEventHandler; diff --git a/src/types/events.ts b/src/types/events.ts index c48e769fcc..6d3e0d9e41 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -4,6 +4,7 @@ import type { OnAudioTracksData, OnBandwidthUpdateData, OnBufferData, + OnControlsVisibilityChange, OnExternalPlaybackChangeData, OnLoadStartData, OnPictureInPictureStatusChangedData, @@ -237,6 +238,7 @@ export interface ReactVideoEvents { onIdle?: () => void; // Android onBandwidthUpdate?: (e: OnBandwidthUpdateData) => void; //Android onBuffer?: (e: OnBufferData) => void; //Android, iOS + onControlsVisibilityChange?: (e: OnControlsVisibilityChange) => void; // Android, iOS onEnd?: () => void; //All onError?: (e: OnVideoErrorData) => void; //Android, iOS onExternalPlaybackChange?: (e: OnExternalPlaybackChangeData) => void; //iOS From d01f6605f94b436201ef5a872e9dea757279f141 Mon Sep 17 00:00:00 2001 From: Ash Mishra Date: Wed, 19 Jun 2024 13:05:03 -0700 Subject: [PATCH 2/5] ESLint corrections --- src/Video.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Video.tsx b/src/Video.tsx index 71f2cd32fa..4bac8bb955 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -466,7 +466,7 @@ const Video = forwardRef( onControlsVisibilityChange?.(e.nativeEvent); }, [onControlsVisibilityChange], - ) + ); const useExternalGetLicense = drm?.getLicense instanceof Function; @@ -625,7 +625,11 @@ const Video = forwardRef( ? (_onReceiveAdEvent as (e: NativeSyntheticEvent) => void) : undefined } - onControlsVisibilityChange={onControlsVisibilityChange ? _onControlsVisibilityChange : undefined} + onControlsVisibilityChange={ + onControlsVisibilityChange + ? _onControlsVisibilityChange + : undefined + } /> {hasPoster && showPoster ? ( From 086ad8adbc1561770e764fccf37533b08da9a1ba Mon Sep 17 00:00:00 2001 From: Ash Mishra Date: Wed, 19 Jun 2024 13:07:05 -0700 Subject: [PATCH 3/5] ESLint corrections --- src/Video.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Video.tsx b/src/Video.tsx index 4bac8bb955..76cb6a3878 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -627,8 +627,8 @@ const Video = forwardRef( } onControlsVisibilityChange={ onControlsVisibilityChange - ? _onControlsVisibilityChange - : undefined + ? _onControlsVisibilityChange + : undefined } /> {hasPoster && showPoster ? ( From d7b4516ecda7268e27bec34ffe8b56541664bf5f Mon Sep 17 00:00:00 2001 From: Ash Mishra Date: Wed, 19 Jun 2024 13:10:06 -0700 Subject: [PATCH 4/5] ESLint corrections --- src/Video.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Video.tsx b/src/Video.tsx index 76cb6a3878..2b814ddd8d 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -626,8 +626,8 @@ const Video = forwardRef( : undefined } onControlsVisibilityChange={ - onControlsVisibilityChange - ? _onControlsVisibilityChange + onControlsVisibilityChange + ? _onControlsVisibilityChange : undefined } /> From ed6e523a88f17bbb55f0a604fc4e5f0e8a093059 Mon Sep 17 00:00:00 2001 From: Ash Mishra Date: Thu, 20 Jun 2024 08:15:27 -0700 Subject: [PATCH 5/5] Eslint fixes --- src/Video.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Video.tsx b/src/Video.tsx index 2b814ddd8d..aa21365ef4 100644 --- a/src/Video.tsx +++ b/src/Video.tsx @@ -393,6 +393,13 @@ const Video = forwardRef( [onVideoTracks], ); + const _onPlaybackRateChange = useCallback( + (e: NativeSyntheticEvent>) => { + onPlaybackRateChange?.(e.nativeEvent); + }, + [onPlaybackRateChange], + ); + const _onVolumeChange = useCallback( (e: NativeSyntheticEvent>) => { onVolumeChange?.(e.nativeEvent); @@ -454,13 +461,6 @@ const Video = forwardRef( [onAspectRatio], ); - const _onPlaybackRateChange = useCallback( - (e: NativeSyntheticEvent>) => { - onPlaybackRateChange?.(e.nativeEvent); - }, - [onPlaybackRateChange], - ); - const _onControlsVisibilityChange = useCallback( (e: NativeSyntheticEvent) => { onControlsVisibilityChange?.(e.nativeEvent); @@ -626,9 +626,7 @@ const Video = forwardRef( : undefined } onControlsVisibilityChange={ - onControlsVisibilityChange - ? _onControlsVisibilityChange - : undefined + onControlsVisibilityChange ? _onControlsVisibilityChange : undefined } /> {hasPoster && showPoster ? (