From a1d112182168489a3aec06a237f9ec9c03c957c0 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sat, 21 Sep 2024 12:53:32 +0330 Subject: [PATCH 1/9] feat(android): show live video label --- .../exoplayer/FullScreenPlayerView.kt | 9 +++ .../exoplayer/ReactExoplayerView.java | 64 +++++++++---------- android/src/main/res/drawable/circle.xml | 6 ++ .../layout/exo_legacy_player_control_view.xml | 38 ++++++++++- android/src/main/res/values/colors.xml | 2 + android/src/main/res/values/dimens.xml | 1 + android/src/main/res/values/strings.xml | 2 + 7 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 android/src/main/res/drawable/circle.xml diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt index e6bad1b0a9..93d3c5d725 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt @@ -10,6 +10,7 @@ import android.view.Window import android.view.WindowManager import android.widget.FrameLayout import android.widget.ImageButton +import android.widget.LinearLayout import androidx.activity.OnBackPressedCallback import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat @@ -216,5 +217,13 @@ class FullScreenPlayerView( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE ) } + if(controlsConfig.hideNotificationBarOnFullScreenMode){ + val liveContainer = playerControlView?.findViewById(com.brentvatne.react.R.id.exo_live_container) + liveContainer?.let { + val layoutParams = it.layoutParams as LinearLayout.LayoutParams + layoutParams.topMargin = 40 + it.layoutParams = layoutParams + } + } } } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 0714115e50..19441e4401 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -466,7 +466,6 @@ public void onVisibilityChange(int visibility) { final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen); fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen)); updateFullScreenButtonVisibility(); - refreshProgressBarVisibility(); // Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player eventListener = new Player.Listener() { @@ -525,41 +524,40 @@ private void reLayout(View view) { view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight()); } - private void refreshProgressBarVisibility (){ - if(playerControlView == null) return; - DefaultTimeBar exoProgress; - TextView exoDuration; - TextView exoPosition; - exoProgress = playerControlView.findViewById(R.id.exo_progress); - exoDuration = playerControlView.findViewById(R.id.exo_duration); - exoPosition = playerControlView.findViewById(R.id.exo_position); - if(controlsConfig.getHideSeekBar()){ - LinearLayout.LayoutParams param = new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT, - 1.0f - ); - exoProgress.setVisibility(GONE); - exoDuration.setVisibility(GONE); - exoPosition.setLayoutParams(param); - }else{ - exoProgress.setVisibility(VISIBLE); - - if(controlsConfig.getHideDuration()){ - exoDuration.setVisibility(GONE); - }else{ - exoDuration.setVisibility(VISIBLE); - } + private void refreshProgressBarVisibility() { + if (playerControlView == null || player == null) return; - // Reset the layout parameters of exoPosition to their default state - LinearLayout.LayoutParams defaultParam = new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ); - exoPosition.setLayoutParams(defaultParam); + DefaultTimeBar exoProgress = playerControlView.findViewById(R.id.exo_progress); + TextView exoDuration = playerControlView.findViewById(R.id.exo_duration); + LinearLayout exoLiveContainer = playerControlView.findViewById(R.id.exo_live_container); + + boolean isLive = false; + Timeline timeline = player.getCurrentTimeline(); + + // Determine if the content is live + if (!timeline.isEmpty()) { + Timeline.Window window = new Timeline.Window(); + timeline.getWindow(player.getCurrentMediaItemIndex(), window); + isLive = window.isLive(); } + + // Handle visibility for live content or hideSeekBar + if (controlsConfig.getHideSeekBar() || isLive) { + exoProgress.setVisibility(View.INVISIBLE); + exoDuration.setVisibility(View.INVISIBLE); + exoLiveContainer.setVisibility(View.VISIBLE); + return; + } + + // Handle visibility for non-live content + exoProgress.setVisibility(View.VISIBLE); + exoLiveContainer.setVisibility(View.GONE); + + // Handle duration visibility based on configuration + exoDuration.setVisibility(controlsConfig.getHideDuration() ? View.INVISIBLE : View.VISIBLE); } + private void reLayoutControls() { reLayout(exoPlayerView); reLayout(playerControlView); @@ -1459,6 +1457,7 @@ private void videoLoaded() { eventEmitter.onVideoLoad.invoke(duration, currentPosition, width, height, audioTracks, textTracks, videoTracks, trackId); + refreshProgressBarVisibility(); } } @@ -2357,6 +2356,7 @@ public void setControls(boolean controls) { removeViewAt(indexOfPC); } } + refreshProgressBarVisibility(); } public void setSubtitleStyle(SubtitleStyle style) { diff --git a/android/src/main/res/drawable/circle.xml b/android/src/main/res/drawable/circle.xml new file mode 100644 index 0000000000..9f06d7c701 --- /dev/null +++ b/android/src/main/res/drawable/circle.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android/src/main/res/layout/exo_legacy_player_control_view.xml b/android/src/main/res/layout/exo_legacy_player_control_view.xml index 50ef45b269..8ba48a7fc8 100644 --- a/android/src/main/res/layout/exo_legacy_player_control_view.xml +++ b/android/src/main/res/layout/exo_legacy_player_control_view.xml @@ -1,17 +1,51 @@ + + + + + + + + + #FFBEBEBE #CC000000 + #FFFFFF + #FF0000 \ No newline at end of file diff --git a/android/src/main/res/values/dimens.xml b/android/src/main/res/values/dimens.xml index 218dca64d6..4336a34cb6 100644 --- a/android/src/main/res/values/dimens.xml +++ b/android/src/main/res/values/dimens.xml @@ -3,6 +3,7 @@ 4dp 4dp + 12dp 4dp 4dp diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 1f037779dd..6211fd557a 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -16,4 +16,6 @@ This device does not support the required DRM scheme An unknown DRM error occurred + + Live From e630c4f461167a299471fc3b82632867672b06c2 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sat, 21 Sep 2024 12:57:08 +0330 Subject: [PATCH 2/9] fix: linter error --- .../main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt index 93d3c5d725..9eff62dd24 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/FullScreenPlayerView.kt @@ -217,7 +217,7 @@ class FullScreenPlayerView( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE ) } - if(controlsConfig.hideNotificationBarOnFullScreenMode){ + if (controlsConfig.hideNotificationBarOnFullScreenMode) { val liveContainer = playerControlView?.findViewById(com.brentvatne.react.R.id.exo_live_container) liveContainer?.let { val layoutParams = it.layoutParams as LinearLayout.LayoutParams From b79ec9fbe3a362dc6aaf1ef1b957a5e1700863e9 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sat, 21 Sep 2024 13:00:50 +0330 Subject: [PATCH 3/9] chore: update function name --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 19441e4401..cfd96921c8 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -524,7 +524,7 @@ private void reLayout(View view) { view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight()); } - private void refreshProgressBarVisibility() { + private void refreshControlsStyles() { if (playerControlView == null || player == null) return; DefaultTimeBar exoProgress = playerControlView.findViewById(R.id.exo_progress); @@ -1457,7 +1457,7 @@ private void videoLoaded() { eventEmitter.onVideoLoad.invoke(duration, currentPosition, width, height, audioTracks, textTracks, videoTracks, trackId); - refreshProgressBarVisibility(); + refreshControlsStyles(); } } @@ -2356,7 +2356,7 @@ public void setControls(boolean controls) { removeViewAt(indexOfPC); } } - refreshProgressBarVisibility(); + refreshControlsStyles(); } public void setSubtitleStyle(SubtitleStyle style) { @@ -2389,6 +2389,6 @@ public void onAdError(AdErrorEvent adErrorEvent) { public void setControlsStyles(ControlsConfig controlsStyles) { controlsConfig = controlsStyles; - refreshProgressBarVisibility(); + refreshControlsStyles(); } } \ No newline at end of file From 8b494a4a8ced4493f0887fc87ea7e4758c17ead0 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sun, 22 Sep 2024 22:24:21 +0330 Subject: [PATCH 4/9] fix: PR feedback --- .../exoplayer/ReactExoplayerView.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index cfd96921c8..0e02055fcf 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -541,20 +541,20 @@ private void refreshControlsStyles() { isLive = window.isLive(); } - // Handle visibility for live content or hideSeekBar - if (controlsConfig.getHideSeekBar() || isLive) { - exoProgress.setVisibility(View.INVISIBLE); - exoDuration.setVisibility(View.INVISIBLE); + if(isLive){ exoLiveContainer.setVisibility(View.VISIBLE); - return; + }else{ + exoLiveContainer.setVisibility(View.GONE); } - // Handle visibility for non-live content - exoProgress.setVisibility(View.VISIBLE); - exoLiveContainer.setVisibility(View.GONE); + if (controlsConfig.getHideSeekBar()) { + exoProgress.setVisibility(View.INVISIBLE); + }else{ + exoProgress.setVisibility(View.VISIBLE); + } - // Handle duration visibility based on configuration - exoDuration.setVisibility(controlsConfig.getHideDuration() ? View.INVISIBLE : View.VISIBLE); + // Handle duration visibility based on configuration or live video + exoDuration.setVisibility(controlsConfig.getHideDuration() || isLive ? View.INVISIBLE : View.VISIBLE); } From 5b5645aa8e757acde0bc28f30d0f6d82678647be Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Fri, 27 Sep 2024 12:34:54 +0330 Subject: [PATCH 5/9] chore: add live label property --- .../main/java/com/brentvatne/common/api/ControlsConfig.kt | 2 ++ .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 5 ++++- .../src/main/res/layout/exo_legacy_player_control_view.xml | 5 +---- android/src/main/res/values/strings.xml | 2 -- examples/basic/src/VideoPlayer.tsx | 4 +++- src/specs/VideoNativeComponent.ts | 1 + src/types/video.ts | 1 + 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt index a50482c658..1221e6e872 100644 --- a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt +++ b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt @@ -9,6 +9,7 @@ class ControlsConfig { var hideDuration: Boolean = false var hideNavigationBarOnFullScreenMode: Boolean = true var hideNotificationBarOnFullScreenMode: Boolean = true + var liveLabel: String? = "" companion object { @JvmStatic @@ -21,6 +22,7 @@ class ControlsConfig { config.hideDuration = ReactBridgeUtils.safeGetBool(src, "hideDuration", false) config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNavigationBarOnFullScreenMode", true) config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true) + config.liveLabel = ReactBridgeUtils.safeGetString(src, "liveLabel", "") } return config } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 0e02055fcf..a9ec1bf3bf 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -139,6 +139,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -530,6 +531,7 @@ private void refreshControlsStyles() { DefaultTimeBar exoProgress = playerControlView.findViewById(R.id.exo_progress); TextView exoDuration = playerControlView.findViewById(R.id.exo_duration); LinearLayout exoLiveContainer = playerControlView.findViewById(R.id.exo_live_container); + TextView exoLiveLabel = playerControlView.findViewById(R.id.exo_live_label); boolean isLive = false; Timeline timeline = player.getCurrentTimeline(); @@ -541,7 +543,8 @@ private void refreshControlsStyles() { isLive = window.isLive(); } - if(isLive){ + if(isLive && !Objects.equals(controlsConfig.getLiveLabel(), "")){ + exoLiveLabel.setText(controlsConfig.getLiveLabel()); exoLiveContainer.setVisibility(View.VISIBLE); }else{ exoLiveContainer.setVisibility(View.GONE); diff --git a/android/src/main/res/layout/exo_legacy_player_control_view.xml b/android/src/main/res/layout/exo_legacy_player_control_view.xml index 8ba48a7fc8..0d4800a817 100644 --- a/android/src/main/res/layout/exo_legacy_player_control_view.xml +++ b/android/src/main/res/layout/exo_legacy_player_control_view.xml @@ -19,17 +19,14 @@ android:id="@+id/exo_live_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:contentDescription="@string/live" android:paddingHorizontal="@dimen/position_duration_horizontal_padding" android:src="@drawable/circle" /> - diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml index 6211fd557a..1f037779dd 100644 --- a/android/src/main/res/values/strings.xml +++ b/android/src/main/res/values/strings.xml @@ -16,6 +16,4 @@ This device does not support the required DRM scheme An unknown DRM error occurred - - Live diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 6381f34bdf..54bbd7bf1a 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -31,6 +31,7 @@ import Video, { type SelectedVideoTrack, type EnumValues, OnBandwidthUpdateData, + ControlsStyles, } from 'react-native-video'; import styles from './styles'; import {type AdditionalSourceInfo} from './types'; @@ -239,9 +240,10 @@ const VideoPlayer: FC = ({}) => { const _renderLoader = showPoster ? () => : undefined; const _subtitleStyle = {subtitlesFollowVideo: true}; - const _controlsStyles = { + const _controlsStyles : ControlsStyles = { hideNavigationBarOnFullScreenMode: true, hideNotificationBarOnFullScreenMode: true, + liveLabel: "LIVE" }; const _bufferConfig = { ...bufferConfig, diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index f210cfccfb..4a9fed4488 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -301,6 +301,7 @@ type ControlsStyles = Readonly<{ seekIncrementMS?: Int32; hideNavigationBarOnFullScreenMode?: WithDefault; hideNotificationBarOnFullScreenMode?: WithDefault; + liveLabel?: string }>; export type OnControlsVisibilityChange = Readonly<{ diff --git a/src/types/video.ts b/src/types/video.ts index 71304080d6..d377dad211 100644 --- a/src/types/video.ts +++ b/src/types/video.ts @@ -253,6 +253,7 @@ export type ControlsStyles = { seekIncrementMS?: number; hideNavigationBarOnFullScreenMode?: boolean; hideNotificationBarOnFullScreenMode?: boolean; + liveLabel?: string }; export interface ReactVideoRenderLoaderProps { From 46bfe7729d4e1c3a90ed78eb2bfff895424904f1 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Fri, 27 Sep 2024 12:37:29 +0330 Subject: [PATCH 6/9] fix: linter error --- src/specs/VideoNativeComponent.ts | 2 +- src/types/video.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index 4a9fed4488..0b0935c09b 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -301,7 +301,7 @@ type ControlsStyles = Readonly<{ seekIncrementMS?: Int32; hideNavigationBarOnFullScreenMode?: WithDefault; hideNotificationBarOnFullScreenMode?: WithDefault; - liveLabel?: string + liveLabel?: string; }>; export type OnControlsVisibilityChange = Readonly<{ diff --git a/src/types/video.ts b/src/types/video.ts index d377dad211..788c5fb976 100644 --- a/src/types/video.ts +++ b/src/types/video.ts @@ -253,7 +253,7 @@ export type ControlsStyles = { seekIncrementMS?: number; hideNavigationBarOnFullScreenMode?: boolean; hideNotificationBarOnFullScreenMode?: boolean; - liveLabel?: string + liveLabel?: string; }; export interface ReactVideoRenderLoaderProps { From 58cb12585a0abd754e64acc3f7358ebb3bf48e68 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sat, 28 Sep 2024 16:16:04 +0330 Subject: [PATCH 7/9] fix: PR feedback --- .../com/brentvatne/common/api/ControlsConfig.kt | 4 ++-- .../brentvatne/exoplayer/ReactExoplayerView.java | 5 ++--- docs/pages/component/props.mdx | 16 +++++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt index 1221e6e872..736474313d 100644 --- a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt +++ b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt @@ -9,7 +9,7 @@ class ControlsConfig { var hideDuration: Boolean = false var hideNavigationBarOnFullScreenMode: Boolean = true var hideNotificationBarOnFullScreenMode: Boolean = true - var liveLabel: String? = "" + var liveLabel: String? = null companion object { @JvmStatic @@ -22,7 +22,7 @@ class ControlsConfig { config.hideDuration = ReactBridgeUtils.safeGetBool(src, "hideDuration", false) config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNavigationBarOnFullScreenMode", true) config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true) - config.liveLabel = ReactBridgeUtils.safeGetString(src, "liveLabel", "") + config.liveLabel = ReactBridgeUtils.safeGetString(src, "liveLabel", null) } return config } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index a9ec1bf3bf..8754149b68 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -139,7 +139,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -526,7 +525,7 @@ private void reLayout(View view) { } private void refreshControlsStyles() { - if (playerControlView == null || player == null) return; + if (playerControlView == null || player == null || !controls) return; DefaultTimeBar exoProgress = playerControlView.findViewById(R.id.exo_progress); TextView exoDuration = playerControlView.findViewById(R.id.exo_duration); @@ -543,7 +542,7 @@ private void refreshControlsStyles() { isLive = window.isLive(); } - if(isLive && !Objects.equals(controlsConfig.getLiveLabel(), "")){ + if(isLive && controlsConfig.getLiveLabel() != null){ exoLiveLabel.setText(controlsConfig.getLiveLabel()); exoLiveContainer.setVisibility(View.VISIBLE); }else{ diff --git a/docs/pages/component/props.mdx b/docs/pages/component/props.mdx index 2129886814..42d1f5d649 100644 --- a/docs/pages/component/props.mdx +++ b/docs/pages/component/props.mdx @@ -144,13 +144,14 @@ If needed, you can also add your controls or use a package like [react-native-vi Adjust the control styles. This prop is need only if `controls={true}` and is an object. See the list of prop supported below. -| Property | Type | Description | -|-----------------------------------|---------|--------------------------------------------------------------------------------------------| -| hideSeekBar | boolean | The default value is `false`, allowing you to hide the seek bar for live broadcasts. | -| hideDuration | boolean | The default value is `false`, allowing you to hide the duration. | -| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. | -| hideNavigationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the navigation bar on full-screen mode. | +| Property | Type | Description | +|-------------------------------------|---------|---------------------------------------------------------------------------------------------| +| hideSeekBar | boolean | The default value is `false`, allowing you to hide the seek bar for live broadcasts. | +| hideDuration | boolean | The default value is `false`, allowing you to hide the duration. | +| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. | +| hideNavigationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the navigation bar on full-screen mode. | | hideNotificationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the notification bar on full-screen mode. | +| liveLabel | string | Allowing you to set a label for live video. | Example with default values: @@ -161,6 +162,7 @@ controlsStyles={{ seekIncrementMS: 10000, hideNavigationBarOnFullScreenMode: true, hideNotificationBarOnFullScreenMode: true, + liveLabel: "LIVE" }} ``` @@ -523,7 +525,7 @@ If `renderLoader` is provided, `poster` and `posterResizeMode` will be ignored. renderLoader is either a component or a function returning a component. It is recommended to use the function for optimization matter. -`renderLoader` function be called with parameters of type `ReactVideoRenderLoaderProps` to be able to adapt loader +`renderLoader` function be called with parameters of type `ReactVideoRenderLoaderProps` to be able to adapt loader ```typescript interface ReactVideoRenderLoaderProps { From cc1a151042312c3a439025abdf63a2f247ee9be0 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Sat, 28 Sep 2024 16:40:09 +0330 Subject: [PATCH 8/9] chore: rename argument parse function in controlsConfig class --- .../com/brentvatne/common/api/ControlsConfig.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt index 736474313d..e6205a8611 100644 --- a/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt +++ b/android/src/main/java/com/brentvatne/common/api/ControlsConfig.kt @@ -13,16 +13,16 @@ class ControlsConfig { companion object { @JvmStatic - fun parse(src: ReadableMap?): ControlsConfig { + fun parse(controlsConfig: ReadableMap?): ControlsConfig { val config = ControlsConfig() - if (src != null) { - config.hideSeekBar = ReactBridgeUtils.safeGetBool(src, "hideSeekBar", false) - config.seekIncrementMS = ReactBridgeUtils.safeGetInt(src, "seekIncrementMS", 10000) - config.hideDuration = ReactBridgeUtils.safeGetBool(src, "hideDuration", false) - config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNavigationBarOnFullScreenMode", true) - config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true) - config.liveLabel = ReactBridgeUtils.safeGetString(src, "liveLabel", null) + if (controlsConfig != null) { + config.hideSeekBar = ReactBridgeUtils.safeGetBool(controlsConfig, "hideSeekBar", false) + config.seekIncrementMS = ReactBridgeUtils.safeGetInt(controlsConfig, "seekIncrementMS", 10000) + config.hideDuration = ReactBridgeUtils.safeGetBool(controlsConfig, "hideDuration", false) + config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(controlsConfig, "hideNavigationBarOnFullScreenMode", true) + config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(controlsConfig, "hideNotificationBarOnFullScreenMode", true) + config.liveLabel = ReactBridgeUtils.safeGetString(controlsConfig, "liveLabel", null) } return config } From c74329704d35394465fe8ec6a497be47f34e8755 Mon Sep 17 00:00:00 2001 From: mostafahasani Date: Mon, 30 Sep 2024 10:17:04 +0330 Subject: [PATCH 9/9] chore: refactor refreshControlsStyles function --- .../exoplayer/ReactExoplayerView.java | 103 ++++++------------ 1 file changed, 36 insertions(+), 67 deletions(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 713df0b671..33f9d205d0 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -527,9 +527,21 @@ private void reLayout(View view) { view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight()); } - private void refreshControlsStyles (){ + private void refreshControlsStyles() { if (playerControlView == null || player == null || !controls) return; - + updateLiveContent(); + updatePlayPauseButtons(); + updateButtonVisibility(controlsConfig.getHideForward(), R.id.exo_ffwd); + updateButtonVisibility(controlsConfig.getHideRewind(), R.id.exo_rew); + updateButtonVisibility(controlsConfig.getHideNext(), R.id.exo_next); + updateButtonVisibility(controlsConfig.getHidePrevious(), R.id.exo_prev); + updateViewVisibility(playerControlView.findViewById(R.id.exo_fullscreen), controlsConfig.getHideFullscreen(), GONE); + updateViewVisibility(playerControlView.findViewById(R.id.exo_position), controlsConfig.getHidePosition(), GONE); + updateViewVisibility(playerControlView.findViewById(R.id.exo_progress), controlsConfig.getHideSeekBar(), INVISIBLE); + updateViewVisibility(playerControlView.findViewById(R.id.exo_duration), controlsConfig.getHideDuration(), GONE); + } + + private void updateLiveContent() { LinearLayout exoLiveContainer = playerControlView.findViewById(R.id.exo_live_container); TextView exoLiveLabel = playerControlView.findViewById(R.id.exo_live_label); @@ -543,93 +555,50 @@ private void refreshControlsStyles (){ isLive = window.isLive(); } - if(isLive && controlsConfig.getLiveLabel() != null){ + if (isLive && controlsConfig.getLiveLabel() != null) { exoLiveLabel.setText(controlsConfig.getLiveLabel()); - exoLiveContainer.setVisibility(View.VISIBLE); - }else{ - exoLiveContainer.setVisibility(View.GONE); + exoLiveContainer.setVisibility(VISIBLE); + } else { + exoLiveContainer.setVisibility(GONE); } + } + private void updatePlayPauseButtons() { final ImageButton playButton = playerControlView.findViewById(R.id.exo_play); final ImageButton pauseButton = playerControlView.findViewById(R.id.exo_pause); + if (controlsConfig.getHidePlayPause()) { playPauseControlContainer.setAlpha(0); - playButton.setClickable(false); pauseButton.setClickable(false); } else { playPauseControlContainer.setAlpha(1.0f); - playButton.setClickable(true); pauseButton.setClickable(true); } + } - final ImageButton forwardButton = playerControlView.findViewById(R.id.exo_ffwd); - if (controlsConfig.getHideForward()) { - forwardButton.setImageAlpha(0); - forwardButton.setClickable(false); - } else { - forwardButton.setImageAlpha(255); - forwardButton.setClickable(true); - } - - final ImageButton rewindButton = playerControlView.findViewById(R.id.exo_rew); - if (controlsConfig.getHideRewind()) { - rewindButton.setImageAlpha(0); - rewindButton.setClickable(false); - } else { - rewindButton.setImageAlpha(255); - rewindButton.setClickable(true); - } - - final ImageButton nextButton = playerControlView.findViewById(R.id.exo_next); - if (controlsConfig.getHideNext()) { - nextButton.setClickable(false); - nextButton.setImageAlpha(0); - } else { - nextButton.setImageAlpha(255); - nextButton.setClickable(true); - } - - final ImageButton previousButton = playerControlView.findViewById(R.id.exo_prev); - if (controlsConfig.getHidePrevious()) { - previousButton.setImageAlpha(0); - previousButton.setClickable(false); + private void updateButtonVisibility(boolean hide, int buttonID) { + ImageButton button = playerControlView.findViewById(buttonID); + if (hide) { + button.setImageAlpha(0); + button.setClickable(false); } else { - previousButton.setImageAlpha(255); - previousButton.setClickable(true); - } - - final ImageButton fullscreenButton = playerControlView.findViewById(R.id.exo_fullscreen); - if (controlsConfig.getHideFullscreen()) { - fullscreenButton.setVisibility(GONE); - } else if (fullscreenButton.getVisibility() == GONE) { - fullscreenButton.setVisibility(VISIBLE); - } - - final TextView positionText = playerControlView.findViewById(R.id.exo_position); - if(controlsConfig.getHidePosition()){ - positionText.setVisibility(GONE); - } else if (positionText.getVisibility() == GONE){ - positionText.setVisibility(VISIBLE); - } - - final DefaultTimeBar progressBar = playerControlView.findViewById(R.id.exo_progress); - if (controlsConfig.getHideSeekBar()) { - progressBar.setVisibility(INVISIBLE); - } else if (progressBar.getVisibility() == INVISIBLE) { - progressBar.setVisibility(VISIBLE); + button.setImageAlpha(255); + button.setClickable(true); } + } - final TextView durationText = playerControlView.findViewById(R.id.exo_duration); - if (controlsConfig.getHideDuration()) { - durationText.setVisibility(GONE); - } else if (durationText.getVisibility() == GONE) { - durationText.setVisibility(VISIBLE); + private void updateViewVisibility(View view, boolean hide, int hideVisibility) { + if (hide) { + view.setVisibility(hideVisibility); + } else if (view.getVisibility() == hideVisibility) { + view.setVisibility(VISIBLE); } } + private void reLayoutControls() { reLayout(exoPlayerView); reLayout(playerControlView);