Skip to content

Commit b6ec2d2

Browse files
committed
adding prop useTextureView={true}
1 parent 6191d99 commit b6ec2d2

8 files changed

Lines changed: 72 additions & 9 deletions

File tree

android/src/main/java/com/video/PlayerCore.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ object PlayerCore {
8686
private var player: ExoPlayer? = null
8787
private var playerView: PlayerView? = null
8888

89+
/**
90+
* Surface type for the singleton PlayerView, set via [setUseTextureView]
91+
* before [initialize] first inflates it. surface_type is only settable via
92+
* layout attrs, hence the two layouts. Changing this after the view exists
93+
* has no effect until the app restarts.
94+
*/
95+
private var useTextureView = true
96+
97+
fun setUseTextureView(value: Boolean) {
98+
useTextureView = value
99+
}
100+
89101
// Second engine: a re-parentable WebView running the YouTube IFrame API.
90102
private enum class Engine { EXO, WEB }
91103
private var engine = Engine.EXO
@@ -171,8 +183,10 @@ object PlayerCore {
171183
player = exo
172184

173185
// Inflated from XML because surface_type can only be set via attrs.
186+
val layoutRes =
187+
if (useTextureView) R.layout.video_player_view else R.layout.video_player_view_surface
174188
val view = LayoutInflater.from(context.applicationContext)
175-
.inflate(R.layout.video_player_view, null) as PlayerView
189+
.inflate(layoutRes, null) as PlayerView
176190
view.player = exo
177191
playerView = view
178192
}

android/src/main/java/com/video/VideoModule.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class VideoModule(reactContext: ReactApplicationContext) :
3535
}
3636
}
3737

38+
override fun setUseTextureView(useTextureView: Boolean) {
39+
PlayerCore.setUseTextureView(useTextureView)
40+
}
41+
3842
override fun releasePlayer() {
3943
UiThreadUtil.runOnUiThread {
4044
PlayerCore.release()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- SurfaceView variant, opted into via setUseTextureView(false). Cheaper to
3+
render than a TextureView but can't be transformed/animated and tends to
4+
black-flash across a re-parent; only used when the app asks for it. -->
5+
<androidx.media3.ui.PlayerView
6+
xmlns:android="http://schemas.android.com/apk/res/android"
7+
xmlns:app="http://schemas.android.com/apk/res-auto"
8+
android:layout_width="match_parent"
9+
android:layout_height="match_parent"
10+
app:surface_type="surface_view"
11+
app:use_controller="false" />

ios/Video.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ - (void)releasePlayer
6969
});
7070
}
7171

72+
- (void)setUseTextureView:(BOOL)useTextureView
73+
{
74+
// TextureView vs. SurfaceView is an Android-only concept (AVPlayerLayer
75+
// has no equivalent choice) — nothing to do on iOS.
76+
}
77+
7278
#pragma mark - Source
7379

7480
- (void)setSource:(NativeVideoSource &)source autoplay:(BOOL)autoplay

scripts/postinstall.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
const force =
1717
process.argv.includes('--force') || process.env.AU_VIDEO_BANNER === '1';
1818

19-
const BANNER = `
20-
________ .___ _________.__ .__
21-
/ _____/ __ _________ __| _/____ ____ ______ / _____/|__| ____ ____ | |__
22-
/ \ ___| | \_ __ \/ __ |/ __ \_/ __ \\____ \ \_____ \ | |/ \ / ___\| | \
23-
\ \_\ \ | /| | \/ /_/ \ ___/\ ___/| |_> > / \| | | \/ /_/ > Y \
24-
\______ /____/ |__| \____ |\___ >\___ > __/ /_______ /|__|___| /\___ /|___| /
25-
\/ \/ \/ \/|__| \/ \//_____/ \/
26-
`;
19+
const BANNER = String.raw`
20+
__ __ ______ _______ ___ __ _ _______ __ __
21+
| |_| || _ | | || | | | | || || | | |
22+
| || | || | _____|| | | |_| || ___|| |_| |
23+
| || |_||_ | |_____ | | | || | __ | |
24+
| || __ | |_____ || | | _ || || || |
25+
| ||_|| || | | | _____| || | | | | || |_| || _ |
26+
|_| |_||___| |_| |_______||___| |_| |__||_______||__| |__|
27+
`;
2728

2829
try {
2930
const quiet = process.env.CI || process.env.npm_config_loglevel === 'silent';

src/NativeVideo.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ export interface Spec extends TurboModule {
6464
/** Idempotent. Creates the singleton native player if needed. */
6565
nativeInit(): void;
6666

67+
/**
68+
* Android only (no-op on iOS): back the player view with a TextureView
69+
* (default) or a SurfaceView. Must be called before `nativeInit()` creates
70+
* the singleton player view — later calls are ignored until the app
71+
* restarts. TextureView re-parents cleanly across surfaces (floating
72+
* window, feed cells) at a small performance cost; SurfaceView is cheaper
73+
* but can't be animated/transformed and misbehaves when re-parented.
74+
*/
75+
setUseTextureView(useTextureView: boolean): void;
76+
6777
/**
6878
* Load a source into the engine. If the currently loaded source has the
6979
* same `id`, this is a no-op (same-video handoff) and playback continues.

src/core/VideoManager.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ export class VideoManager {
154154
liveAutoRetry: true,
155155
resumeOnFocus: true,
156156
debug: false,
157+
useTextureView: true,
157158
};
158159
/** Last non-reserved surface, restored after fullscreen/floating exits. */
159160
private lastInlineSurfaceId: string | null = null;
@@ -271,6 +272,9 @@ export class VideoManager {
271272
return;
272273
}
273274
this.initialized = true;
275+
// Must precede nativeInit(): it decides which surface type Android
276+
// inflates the singleton PlayerView with, and that only happens once.
277+
NativeVideo.setUseTextureView(this.config.useTextureView);
274278
NativeVideo.nativeInit();
275279
this.subscribeNative();
276280
this.setupNetInfo();

src/types/video.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,17 @@ export interface VideoProviderConfig {
168168
* invisible from the outside. Off by default.
169169
*/
170170
debug?: boolean;
171+
/**
172+
* Android only (ignored on iOS). Back the player view with a TextureView
173+
* (default) or a SurfaceView.
174+
*
175+
* TextureView is what makes the player re-parent cleanly between surfaces
176+
* (inline -> fullscreen -> floating, feed cells) without a black flash, at
177+
* a small rendering-performance cost. SurfaceView is cheaper but can't be
178+
* animated or transformed and tends to show a black frame across a
179+
* re-parent — only worth it if the app never moves the player between
180+
* surfaces. Applied once, at provider init; changing it later has no
181+
* effect until the app restarts. Default true.
182+
*/
183+
useTextureView?: boolean;
171184
}

0 commit comments

Comments
 (0)