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

chore(android): rework view type #3940

Merged
merged 29 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d3fc4fd
perf: ensure we do not provide callback to native if no callback prov…
freeboub May 5, 2024
e1da32d
chore: rework bufferConfig to make it more generic and reduce ReactEx…
freeboub May 6, 2024
df3da43
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 8, 2024
0f33ad1
chore: improve issue template
freeboub May 8, 2024
17f2385
Merge branch 'TheWidlarzGroup:master' into master
freeboub May 10, 2024
1066898
fix(android): avoid video view flickering at playback startup
freeboub May 10, 2024
485f867
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 11, 2024
a5e10a3
Merge branch 'master' of github.com:freeboub/react-native-video into …
freeboub May 11, 2024
9ce1d95
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 15, 2024
fa27db7
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 17, 2024
be681d3
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 21, 2024
2fadb26
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 23, 2024
92df10d
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 24, 2024
aa61388
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 28, 2024
ceafc53
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 30, 2024
d30c5f5
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub May 30, 2024
f3f8663
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 3, 2024
5f8c461
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 4, 2024
0eba6da
fix: ensure player doesn't start when view is unmounted
freeboub Jun 4, 2024
8693dbc
Fix/ensure view drop stop playback startup (#3875)
freeboub Jun 6, 2024
89c0e96
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 7, 2024
c42bebd
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 14, 2024
39de902
Merge branch 'TheWidlarzGroup:master' into master
freeboub Jun 18, 2024
ed88143
Merge branch 'master' of github.com:freeboub/react-native-video
freeboub Jun 18, 2024
24321eb
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 21, 2024
e180abc
Merge branch 'master' of github.com:react-native-video/react-native-v…
freeboub Jun 22, 2024
90bf6c6
chore(android): rework viewType management
freeboub Jun 24, 2024
a7d6fb3
chore: code clean & use enum
freeboub Jun 24, 2024
ba500f9
chore: move code into a memo
freeboub Jun 27, 2024
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
19 changes: 19 additions & 0 deletions android/src/main/java/com/brentvatne/common/api/ViewType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.brentvatne.common.api

internal object ViewType {
/**
* View used will be a TextureView.
*/
const val VIEW_TYPE_TEXTURE = 0

/**
* View used will be a SurfaceView.
*/
const val VIEW_TYPE_SURFACE = 1

/**
* View used will be a SurfaceView with secure flag set.
*/
const val VIEW_TYPE_SURFACE_SECURE = 2
annotation class ViewType
}
65 changes: 30 additions & 35 deletions android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@

import com.brentvatne.common.api.ResizeMode;
import com.brentvatne.common.api.SubtitleStyle;
import com.brentvatne.common.api.ViewType;
import com.brentvatne.common.toolbox.DebugLog;
import com.google.common.collect.ImmutableList;

import java.util.List;

public final class ExoPlayerView extends FrameLayout implements AdViewProvider {

private final static String TAG = "ExoPlayerView";
private View surfaceView;
private final View shutterView;
private final SubtitleView subtitleLayout;
Expand All @@ -42,8 +44,7 @@ public final class ExoPlayerView extends FrameLayout implements AdViewProvider {
private final ViewGroup.LayoutParams layoutParams;
private final FrameLayout adOverlayFrameLayout;

private boolean useTextureView = true;
private boolean useSecureView = false;
private @ViewType.ViewType int viewType = ViewType.VIEW_TYPE_SURFACE;
private boolean hideShutterView = false;

public ExoPlayerView(Context context) {
Expand Down Expand Up @@ -81,7 +82,7 @@ public ExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
subtitleLayout.setUserDefaultStyle();
subtitleLayout.setUserDefaultTextSize();

updateSurfaceView();
updateSurfaceView(viewType);

adOverlayFrameLayout = new FrameLayout(context);

Expand Down Expand Up @@ -134,28 +135,36 @@ public void setShutterColor(Integer color) {
shutterView.setBackgroundColor(color);
}

private void updateSurfaceView() {
View view;
if (!useTextureView || useSecureView) {
view = new SurfaceView(context);
if (useSecureView) {
((SurfaceView)view).setSecure(true);
public void updateSurfaceView(@ViewType.ViewType int viewType) {
this.viewType = viewType;
boolean viewNeedRefresh = false;
if (viewType == ViewType.VIEW_TYPE_SURFACE || viewType == ViewType.VIEW_TYPE_SURFACE_SECURE) {
if (!(surfaceView instanceof SurfaceView)) {
surfaceView = new SurfaceView(context);
viewNeedRefresh = true;
}
((SurfaceView)surfaceView).setSecure(viewType == ViewType.VIEW_TYPE_SURFACE_SECURE);
} else if (viewType == ViewType.VIEW_TYPE_TEXTURE) {
if (!(surfaceView instanceof TextureView)) {
surfaceView = new TextureView(context);
viewNeedRefresh = true;
}
} else {
view = new TextureView(context);
// Support opacity properly:
((TextureView) view).setOpaque(false);
((TextureView) surfaceView).setOpaque(false);
} else {
DebugLog.wtf(TAG, "wtf is this texture " + viewType);
}
view.setLayoutParams(layoutParams);
if (viewNeedRefresh) {
surfaceView.setLayoutParams(layoutParams);

surfaceView = view;
if (layout.getChildAt(0) != null) {
layout.removeViewAt(0);
}
layout.addView(surfaceView, 0, layoutParams);
if (layout.getChildAt(0) != null) {
layout.removeViewAt(0);
}
layout.addView(surfaceView, 0, layoutParams);

if (this.player != null) {
setVideoView();
if (this.player != null) {
setVideoView();
}
}
}

Expand Down Expand Up @@ -211,20 +220,6 @@ public void setResizeMode(@ResizeMode.Mode int resizeMode) {
}
}

public void setUseTextureView(boolean useTextureView) {
if (useTextureView != this.useTextureView) {
this.useTextureView = useTextureView;
updateSurfaceView();
}
}

public void useSecureView(boolean useSecureView) {
if (useSecureView != this.useSecureView) {
this.useSecureView = useSecureView;
updateSurfaceView();
}
}

public void setHideShutterView(boolean hideShutterView) {
this.hideShutterView = hideShutterView;
updateShutterViewVisibility();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,10 @@ private void refreshDebugState() {
}
}

public void setViewType(int viewType) {
exoPlayerView.updateSurfaceView(viewType);
}

private class RNVLoadControl extends DefaultLoadControl {
private final int availableHeapInBytes;
private final Runtime runtime;
Expand Down Expand Up @@ -2237,15 +2241,6 @@ public void setFullscreen(boolean fullscreen) {
updateFullScreenButtonVisibility();
}

public void setUseTextureView(boolean useTextureView) {
boolean finallyUseTextureView = useTextureView && drmProps == null;
exoPlayerView.setUseTextureView(finallyUseTextureView);
}

public void useSecureView(boolean useSecureView) {
exoPlayerView.useSecureView(useSecureView);
}

public void setHideShutterView(boolean hideShutterView) {
exoPlayerView.setHideShutterView(hideShutterView);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.brentvatne.common.api.SideLoadedTextTrackList;
import com.brentvatne.common.api.Source;
import com.brentvatne.common.api.SubtitleStyle;
import com.brentvatne.common.api.ViewType;
import com.brentvatne.common.react.VideoEventEmitter;
import com.brentvatne.common.toolbox.DebugLog;
import com.brentvatne.common.toolbox.ReactBridgeUtils;
Expand Down Expand Up @@ -68,8 +69,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_DISABLE_DISCONNECT_ERROR = "disableDisconnectError";
private static final String PROP_FOCUSABLE = "focusable";
private static final String PROP_FULLSCREEN = "fullscreen";
private static final String PROP_USE_TEXTURE_VIEW = "useTextureView";
private static final String PROP_SECURE_VIEW = "useSecureView";
private static final String PROP_VIEW_TYPE = "viewType";
private static final String PROP_SELECTED_VIDEO_TRACK = "selectedVideoTrack";
private static final String PROP_SELECTED_VIDEO_TRACK_TYPE = "type";
private static final String PROP_SELECTED_VIDEO_TRACK_VALUE = "value";
Expand Down Expand Up @@ -118,7 +118,6 @@ public void onDropViewInstance(ReactExoplayerView view) {
public void setDRM(final ReactExoplayerView videoView, @Nullable ReadableMap drm) {
DRMProps drmProps = DRMProps.parse(drm);
videoView.setDrm(drmProps);
videoView.setUseTextureView(false);
}

@ReactProp(name = PROP_SRC)
Expand Down Expand Up @@ -298,14 +297,9 @@ public void setFullscreen(final ReactExoplayerView videoView, final boolean full
videoView.setFullscreen(fullscreen);
}

@ReactProp(name = PROP_USE_TEXTURE_VIEW, defaultBoolean = true)
public void setUseTextureView(final ReactExoplayerView videoView, final boolean useTextureView) {
videoView.setUseTextureView(useTextureView);
}

@ReactProp(name = PROP_SECURE_VIEW, defaultBoolean = true)
public void useSecureView(final ReactExoplayerView videoView, final boolean useSecureView) {
videoView.useSecureView(useSecureView);
@ReactProp(name = PROP_VIEW_TYPE, defaultInt = ViewType.VIEW_TYPE_SURFACE)
public void setViewType(final ReactExoplayerView videoView, final int viewType) {
videoView.setViewType(viewType);
}

@ReactProp(name = PROP_HIDE_SHUTTER_VIEW, defaultBoolean = false)
Expand Down
20 changes: 20 additions & 0 deletions docs/pages/component/props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,9 @@ To customize the notification controls you can use `metadata` property in the `s

### `useSecureView`

> [!WARNING]
> deprecated, use viewType instead

<PlatformsList types={['Android']} />

Force the output to a SurfaceView and enables the secure surface.
Expand All @@ -899,8 +902,13 @@ SurfaceView is is the only one that can be labeled as secure.
- **true** - Use security
- **false (default)** - Do not use security



### `useTextureView`

> [!WARNING]
> deprecated, use viewType instead

<PlatformsList types={['Android']} />

Controls whether to output to a TextureView or SurfaceView.
Expand All @@ -915,6 +923,18 @@ useTextureView can only be set at same time you're setting the source.
- **true (default)** - Use a TextureView
- **false** - Use a SurfaceView

### `viewType`

<PlatformsList types={['Android']} />

Allow to explicitly specify view type.
This flag replace `useSecureView` and `useTextureView` fields.
There are 3 available values:
- 'textureView': The video is rendered in a texture view. it allows mapping the view on a texture (useful for 3D).
DRM playback is not supported on textureView, if drm prop is provided, the suface will be transformed to a SurfaceView.
- 'surfaceView' (default): The video is rendered in a surface. take less resources to be rendered.
- 'secureView': The video is rendered in a surface which disallow taking screenshot of the video

### `volume`

<PlatformsList types={['All']} />
Expand Down
43 changes: 38 additions & 5 deletions src/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ import {
resolveAssetSourceForVideo,
} from './utils';
import {VideoManager} from './specs/VideoNativeComponent';
import type {
OnLoadData,
OnTextTracksData,
OnReceiveAdEventData,
ReactVideoProps,
import {
type OnLoadData,
type OnTextTracksData,
type OnReceiveAdEventData,
type ReactVideoProps,
ViewType,
} from './types';

export type VideoSaveData = {
Expand Down Expand Up @@ -84,6 +85,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
selectedVideoTrack,
selectedAudioTrack,
selectedTextTrack,
useTextureView,
useSecureView,
viewType,
onLoadStart,
onLoad,
onError,
Expand Down Expand Up @@ -571,6 +575,34 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
],
);

const hasValidDrmProp = drm !== undefined && Object.keys(drm).length !== 0;

const shallForceViewType =
hasValidDrmProp && (viewType === ViewType.TEXTURE || useTextureView);

if (shallForceViewType) {
console.warn(
'cannot use DRM on texture view. please set useTextureView={false}',
);
}
if (useSecureView && useTextureView) {
console.warn(
'cannot use SecureView on texture view. please set useTextureView={false}',
);
}

const _viewType = shallForceViewType
freeboub marked this conversation as resolved.
Show resolved Hide resolved
? useSecureView
? ViewType.SURFACE_SECURE
: ViewType.SURFACE // check if we should force the type to Surface due to DRM
: viewType
? viewType // else use ViewType from source
: useSecureView // else infer view type from useSecureView and useTextureView
? ViewType.SURFACE_SECURE
: useTextureView
? ViewType.TEXTURE
: ViewType.SURFACE;

return (
<View style={style}>
<NativeVideoComponent
Expand Down Expand Up @@ -651,6 +683,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onControlsVisibilityChange={
onControlsVisibilityChange ? _onControlsVisibilityChange : undefined
}
viewType={_viewType}
/>
{hasPoster && showPoster ? (
<Image style={posterStyle} source={{uri: poster}} />
Expand Down
3 changes: 1 addition & 2 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,7 @@ export interface VideoNativeProps extends ViewProps {
minLoadRetryCount?: Int32; // Android
reportBandwidth?: boolean; //Android
subtitleStyle?: SubtitleStyle; // android
useTextureView?: boolean; // Android
useSecureView?: boolean; // Android
viewType?: Int32; // Android
bufferingStrategy?: BufferingStrategyType; // Android
controlsStyles?: ControlsStyles; // Android
onControlsVisibilityChange?: DirectEventHandler<OnControlsVisibilityChange>;
Expand Down
11 changes: 11 additions & 0 deletions src/types/ViewType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Define Available view type for android
* these values shall match android spec, see ViewType.kt
*/
enum ResizeMode {
TEXTURE = 0,
SURFACE = 1,
SURFACE_SECURE = 2,
}

export default ResizeMode;
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export * from './language';
export {default as Orientation} from './Orientation';
export {default as ResizeMode} from './ResizeMode';
export {default as TextTrackType} from './TextTrackType';
export {default as ViewType} from './ViewType';
export * from './video';
export * from '../specs/VideoNativeComponent';
6 changes: 4 additions & 2 deletions src/types/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {ReactVideoEvents} from './events';
import type {StyleProp, ViewProps, ViewStyle} from 'react-native';
import type VideoResizeMode from './ResizeMode';
import type FilterType from './FilterType';
import type ViewType from './ViewType';

export type Headers = Record<string, string>;

Expand Down Expand Up @@ -256,8 +257,9 @@ export interface ReactVideoProps extends ReactVideoEvents, ViewProps {
shutterColor?: string; // Android
textTracks?: TextTracks;
testID?: string;
useTextureView?: boolean; // Android
useSecureView?: boolean; // Android
viewType?: ViewType;
useTextureView?: boolean; // Android // deprecated
useSecureView?: boolean; // Android // deprecated
volume?: number;
localSourceEncryptionKeyScheme?: string;
debug?: DebugConfig;
Expand Down
Loading