Skip to content
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

fix(android): add subtitleStyle.subtitlesFollowVideo prop to control subtitles positionning #4133

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand All @@ -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 {
Expand All @@ -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
}
}
Expand Down
26 changes: 22 additions & 4 deletions android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 = new SubtitleStyle();

public ExoPlayerView(Context context) {
super(context, null, 0);

Expand Down Expand Up @@ -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() {
Expand All @@ -107,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();

Expand All @@ -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) {
Expand Down
41 changes: 33 additions & 8 deletions docs/pages/component/props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -846,21 +846,46 @@ 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 |
<PlatformsList types={['Android', 'iOS']} />

| 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:

```javascript
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`

<PlatformsList types={['Android', 'iOS', 'visionOS']} />
Expand Down
1 change: 1 addition & 0 deletions examples/basic/src/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ const VideoPlayer: FC<Props> = ({}) => {
onPlaybackStateChanged={onPlaybackStateChanged}
bufferingStrategy={BufferingStrategyType.DEFAULT}
debug={{enable: true, thread: true}}
subtitleStyle={{subtitlesFollowVideo: true}}
/>
</TouchableOpacity>
)}
Expand Down
1 change: 1 addition & 0 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type SubtitleStyle = Readonly<{
paddingLeft?: WithDefault<Float, 0>;
paddingRight?: WithDefault<Float, 0>;
opacity?: WithDefault<Float, 1>;
subtitlesFollowVideo?: WithDefault<boolean, true>;
}>;

type OnLoadData = Readonly<{
Expand Down
1 change: 1 addition & 0 deletions src/types/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export type SubtitleStyle = {
paddingLeft?: number;
paddingRight?: number;
opacity?: number;
subtitlesFollowVideo?: boolean;
};

export enum TextTrackType {
Expand Down
Loading