From 543f413afb436ea6e74f00bbfed1bd0e3280a21b Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sun, 1 Sep 2024 16:07:09 +0200 Subject: [PATCH 1/5] fix(android): add subtitleStyle.subtitlesFollowVideo prop to control subtitles positionning --- .../brentvatne/common/api/SubtitleStyle.kt | 4 ++++ .../brentvatne/exoplayer/ExoPlayerView.java | 24 ++++++++++++++++--- examples/basic/src/VideoPlayer.tsx | 1 + src/specs/VideoNativeComponent.ts | 1 + src/types/video.ts | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt b/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt index efb4da0a81..e9fb3a048c 100644 --- a/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt +++ b/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt @@ -19,6 +19,8 @@ class SubtitleStyle private constructor() { private set var opacity = 1f private set + var subtitlesFollowVideo = true + private set companion object { private const val PROP_FONT_SIZE_TRACK = "fontSize" @@ -27,6 +29,7 @@ class SubtitleStyle private constructor() { private const val PROP_PADDING_LEFT = "paddingLeft" private const val PROP_PADDING_RIGHT = "paddingRight" private const val PROP_OPACITY = "opacity" + private const val PROP_SUBTITLES_FOLLOW_VIDEO = "subtitlesFollowVideo" @JvmStatic fun parse(src: ReadableMap?): SubtitleStyle { @@ -37,6 +40,7 @@ class SubtitleStyle private constructor() { subtitleStyle.paddingLeft = ReactBridgeUtils.safeGetInt(src, PROP_PADDING_LEFT, 0) subtitleStyle.paddingRight = ReactBridgeUtils.safeGetInt(src, PROP_PADDING_RIGHT, 0) subtitleStyle.opacity = ReactBridgeUtils.safeGetFloat(src, PROP_OPACITY, 1f) + subtitleStyle.subtitlesFollowVideo = ReactBridgeUtils.safeGetBool(src, PROP_SUBTITLES_FOLLOW_VIDEO, true) return subtitleStyle } } diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java index dd18dbfd5b..0b95b1f69e 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java @@ -48,6 +48,8 @@ public final class ExoPlayerView extends FrameLayout implements AdViewProvider { private @ViewType.ViewType int viewType = ViewType.VIEW_TYPE_SURFACE; private boolean hideShutterView = false; + private SubtitleStyle localStyle = SubtitleStyle.parse(null); + public ExoPlayerView(Context context) { super(context, null, 0); @@ -80,10 +82,15 @@ public ExoPlayerView(Context context) { adOverlayFrameLayout = new FrameLayout(context); layout.addView(shutterView, 1, layoutParams); - layout.addView(adOverlayFrameLayout, 2, layoutParams); + if (localStyle.getSubtitlesFollowVideo()) { + layout.addView(subtitleLayout, layoutParams); + layout.addView(adOverlayFrameLayout, layoutParams); + } addViewInLayout(layout, 0, aspectRatioParams); - addViewInLayout(subtitleLayout, 1, layoutParams); + if (!localStyle.getSubtitlesFollowVideo()) { + addViewInLayout(subtitleLayout, 1, layoutParams); + } } private void clearVideoView() { @@ -121,7 +128,18 @@ public void setSubtitleStyle(SubtitleStyle style) { } else { subtitleLayout.setVisibility(View.GONE); } - + if (localStyle.getSubtitlesFollowVideo() != style.getSubtitlesFollowVideo()) { + // No need to manipulate layout if value didn't change + if (style.getSubtitlesFollowVideo()) { + removeViewInLayout(subtitleLayout); + layout.addView(subtitleLayout, layoutParams); + } else { + layout.removeViewInLayout(subtitleLayout); + addViewInLayout(subtitleLayout, 1, layoutParams, false); + } + requestLayout(); + } + localStyle = style; } public void setShutterColor(Integer color) { diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 243d2fa8f5..b77f97c9da 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -268,6 +268,7 @@ const VideoPlayer: FC = ({}) => { onPlaybackStateChanged={onPlaybackStateChanged} bufferingStrategy={BufferingStrategyType.DEFAULT} debug={{enable: true, thread: true}} + subtitleStyle={{subtitlesFollowVideo: true}} /> )} diff --git a/src/specs/VideoNativeComponent.ts b/src/specs/VideoNativeComponent.ts index a5eba10c38..82b92745a8 100644 --- a/src/specs/VideoNativeComponent.ts +++ b/src/specs/VideoNativeComponent.ts @@ -131,6 +131,7 @@ type SubtitleStyle = Readonly<{ paddingLeft?: WithDefault; paddingRight?: WithDefault; opacity?: WithDefault; + subtitlesFollowVideo?: WithDefault; }>; type OnLoadData = Readonly<{ diff --git a/src/types/video.ts b/src/types/video.ts index d29d0108a9..b34becb5e0 100644 --- a/src/types/video.ts +++ b/src/types/video.ts @@ -168,6 +168,7 @@ export type SubtitleStyle = { paddingLeft?: number; paddingRight?: number; opacity?: number; + subtitlesFollowVideo?: boolean; }; export enum TextTrackType { From 6898830bde34e129260d4d9cce057d323d09636e Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sun, 1 Sep 2024 16:19:58 +0200 Subject: [PATCH 2/5] docs: add new prop description --- docs/pages/component/props.mdx | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/pages/component/props.mdx b/docs/pages/component/props.mdx index e32865969e..ae0b68c502 100644 --- a/docs/pages/component/props.mdx +++ b/docs/pages/component/props.mdx @@ -854,6 +854,8 @@ source={{ | paddingLeft | Adjust the left padding of the subtitles. Default: 0 | Android | | paddingRight | Adjust the right padding of the subtitles. Default: 0 | Android | | opacity | Adjust the visibility of subtitles with 0 hiding and 1 fully showing them. Android supports float values between 0 and 1 for varying opacity levels, whereas iOS supports only 0 or 1. Default: 1. | Android, iOS | +| subtitlesFollowVideo | Boolean to adjust position of subtitles. Default: true | + Example: @@ -861,6 +863,27 @@ Example: subtitleStyle={{ paddingBottom: 50, fontSize: 20, opacity: 0 }} ``` +Note for `subtitlesFollowVideo` + +`subtitlesFollowVideo` helps to determine how the subtitles are positionned. +To understand this prop you need to understand how views management works. +The main View style passed to react native video is the position reserved to display the video component. +It may not match exactly the real video size. +For exemple, you can pass a 4:3 video view and render a 16:9 video inside. +So there is a second view, the video view. + +Subtitles are managed in a third view. + +First react-native-video resize the video to keep aspect ratio (depending on `resizeMode` property) and put it in main view. + +* When putting subtitlesFollowVideo to true, the subtitle view will be adapt to the video view. +It means that if the video is displayed out of screen, the subtitles may also be displayed out of screen. + +* When putting subtitlesFollowVideo to false, the subtitle view will keep adapting to the main view. +It means that if the video is displayed out of screen, the subtitles may also be displayed out of screen. + +This prop can be changed on runtime. + ### `textTracks` From cc7b221cc0b521556215bc55c7c2e4220ed39507 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sun, 1 Sep 2024 21:55:21 +0200 Subject: [PATCH 3/5] docs: add supported platform for subtitleStyle --- docs/pages/component/props.mdx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/pages/component/props.mdx b/docs/pages/component/props.mdx index ae0b68c502..47971ba83e 100644 --- a/docs/pages/component/props.mdx +++ b/docs/pages/component/props.mdx @@ -846,15 +846,17 @@ source={{ ### `subtitleStyle` -| Property | Description | Platforms | -| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| fontSize | Adjust the font size of the subtitles. Default: font size of the device | Android | -| paddingTop | Adjust the top padding of the subtitles. Default: 0 | Android | -| paddingBottom | Adjust the bottom padding of the subtitles. Default: 0 | Android | -| paddingLeft | Adjust the left padding of the subtitles. Default: 0 | Android | -| paddingRight | Adjust the right padding of the subtitles. Default: 0 | Android | -| opacity | Adjust the visibility of subtitles with 0 hiding and 1 fully showing them. Android supports float values between 0 and 1 for varying opacity levels, whereas iOS supports only 0 or 1. Default: 1. | Android, iOS | -| subtitlesFollowVideo | Boolean to adjust position of subtitles. Default: true | + + +| Property | Platform | Description | Platforms | +| ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| fontSize | Android | Adjust the font size of the subtitles. Default: font size of the device | Android | +| paddingTop | Android | Adjust the top padding of the subtitles. Default: 0 | Android | +| paddingBottom | Android | Adjust the bottom padding of the subtitles. Default: 0 | Android | +| paddingLeft | Android | Adjust the left padding of the subtitles. Default: 0 | Android | +| paddingRight | Android | Adjust the right padding of the subtitles. Default: 0 | Android | +| opacity | Android, iOS | Adjust the visibility of subtitles with 0 hiding and 1 fully showing them. Android supports float values between 0 and 1 for varying opacity levels, whereas iOS supports only 0 or 1. Default: 1. | Android, iOS | +| subtitlesFollowVideo | Android | Boolean to adjust position of subtitles. Default: true | Example: From 3366cb7ea7a47d249942adc05a677aa79d40c0c0 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sun, 1 Sep 2024 22:43:33 +0200 Subject: [PATCH 4/5] chore: fix typo in comment --- .../src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java index 0b95b1f69e..1fc7a5e275 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java @@ -114,7 +114,7 @@ public boolean isPlaying() { } public void setSubtitleStyle(SubtitleStyle style) { - // ensure we reset subtile style before reapplying it + // ensure we reset subtitle style before reapplying it subtitleLayout.setUserDefaultStyle(); subtitleLayout.setUserDefaultTextSize(); From 22ca149e0d55dda93fafb2d4d0b4c950f585ab4f Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Mon, 2 Sep 2024 12:05:31 +0200 Subject: [PATCH 5/5] chore: use constructor instead of parse --- .../src/main/java/com/brentvatne/common/api/SubtitleStyle.kt | 2 +- .../src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt b/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt index e9fb3a048c..1ac0fd03ac 100644 --- a/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt +++ b/android/src/main/java/com/brentvatne/common/api/SubtitleStyle.kt @@ -6,7 +6,7 @@ import com.facebook.react.bridge.ReadableMap /** * Helper file to parse SubtitleStyle prop and build a dedicated class */ -class SubtitleStyle private constructor() { +class SubtitleStyle public constructor() { var fontSize = -1 private set var paddingLeft = 0 diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java index 1fc7a5e275..45624d6fa6 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java @@ -48,7 +48,7 @@ public final class ExoPlayerView extends FrameLayout implements AdViewProvider { private @ViewType.ViewType int viewType = ViewType.VIEW_TYPE_SURFACE; private boolean hideShutterView = false; - private SubtitleStyle localStyle = SubtitleStyle.parse(null); + private SubtitleStyle localStyle = new SubtitleStyle(); public ExoPlayerView(Context context) { super(context, null, 0);