Skip to content

Commit b21cbec

Browse files
committed
Fix: Creating WebView Native Reference sharing like Exo Player in android and ios
1 parent 97beaa2 commit b21cbec

19 files changed

Lines changed: 497 additions & 469 deletions

AGENTS.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,47 @@ videoId changes
366366

367367
replace media source.
368368

369+
=========================================================
370+
YOUTUBE (DUAL ENGINE) — IMPLEMENTED
371+
=========================================================
372+
373+
The core supports TWO playback engines behind ONE surface registry:
374+
375+
• ExoPlayer / AVPlayer → source.type = "url" (default; streams/files)
376+
• Native WebView → source.type = "youtube" (uri = YouTube video id)
377+
378+
Do NOT use react-native-video OR react-native-webview OR any JS/third-party
379+
YouTube library for this. The YouTube engine is a NATIVE, singleton,
380+
re-parentable view:
381+
382+
• Android → android.webkit.WebView
383+
• iOS → WKWebView
384+
385+
Same rules as the native player:
386+
387+
• Created once, lives for the app lifetime.
388+
• Re-parented between surfaces (inline ↔ fullscreen ↔ floating) by moving the
389+
WHOLE native view — never reloaded. The web page / playing video moves with
390+
it, so switching to fullscreen keeps the exact same WebView reference and
391+
playback position (no reload, no restart, no re-buffer).
392+
• attach()/detach() move whichever engine's view is active.
393+
394+
Loading:
395+
396+
• Runs the YouTube IFrame Player API with controls:0 (YouTube's own UI is
397+
hidden — the library's <VideoControls> is used, same as native video).
398+
• Loaded with a youtube.com origin/referrer so referrer-restricted embeds
399+
play (avoids the embed "configuration error" / Error 153).
400+
401+
Bridge:
402+
403+
• Native captures the IFrame API postMessage events and emits the SAME core
404+
events (onStatusChange / onLoad / onProgress / onEnd / onError).
405+
• Commands (play/pause/seek/rate/volume/mute) are forwarded into the player
406+
via evaluateJavascript / evaluateJavaScript.
407+
• So usePlayback, useVideoEvents and the useVideo() command API work
408+
identically for url and youtube — the two source types are interchangeable.
409+
369410
=========================================================
370411
PRELOAD
371412
=========================================================

AuVideo.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
1111
s.authors = package["author"]
1212

1313
s.platforms = { :ios => min_ios_version_supported }
14-
s.source = { :git => "https://github.com/gurdeep99/react-native-au-video.git", :tag => "#{s.version}" }
14+
s.source = { :git => "https://github.com/gurdeep99/react-native-video-provider.git", :tag => "#{s.version}" }
1515

1616
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
1717
s.private_header_files = "ios/**/*.h"

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ The [example app](/example/) demonstrates usage of the library. You need to run
2525

2626
It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app.
2727

28-
If you want to use Android Studio or Xcode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/AuVideoExample.xcworkspace` in Xcode and find the source files at `Pods > Development Pods > react-native-au-video`.
28+
If you want to use Android Studio or Xcode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/AuVideoExample.xcworkspace` in Xcode and find the source files at `Pods > Development Pods > react-native-video-provider`.
2929

30-
To edit the Java or Kotlin files, open `example/android` in Android studio and find the source files at `react-native-au-video` under `Android`.
30+
To edit the Java or Kotlin files, open `example/android` in Android studio and find the source files at `react-native-video-provider` under `Android`.
3131

3232
You can use various commands from the root directory to work with the project.
3333

README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Feed ──▶ Detail ──▶ Fullscreen (rotation unlocked) ──▶ Floatin
2020
the engine; the player just re-parents to the new surface
2121
- 📱 **Single-engine feed**`VideoFeed`, a TikTok/Reels-style list where
2222
only the scrolled-into-focus video plays, on one player, flat memory
23+
- ▶️ **YouTube built in**`type: 'youtube'`; a second native, re-parentable
24+
WebView engine with the same controls, fullscreen and handoff (no extra dep)
2325
- 📺 **Fullscreen** — built-in host that locks landscape (no accidental
2426
sensor rotation) and restores the previous orientation on exit
2527
- 🧭 **Orientation control** — force portrait/landscape (+ inverted) per
@@ -42,9 +44,8 @@ cd ios && pod install
4244
```
4345

4446
`react-native-svg` is a peer dependency (used by the built-in control icons).
45-
For YouTube sources add **`react-native-webview`**
46-
(`npm install react-native-webview`) — an optional peer dependency, only
47-
needed if you use `type: 'youtube'`.
47+
YouTube (`type: 'youtube'`) needs **no extra dependency** — it runs on a native
48+
WebView (Android `WebView` / iOS `WKWebView`) built into the library.
4849

4950
Requires the New Architecture. Works on React Native **0.79+** — the
5051
TurboModule spec uses direct codegen-type imports so it parses on 0.79's
@@ -85,17 +86,15 @@ set `type: 'youtube'` and put the YouTube **video id** in `uri`:
8586
<VideoPlayer source={{ id: 'y1', uri: 'dQw4w9WgXcQ', type: 'youtube' }} style={{ aspectRatio: 16 / 9 }} />
8687
```
8788

88-
YouTube plays in a WebView (embed URL + `Referer` header — the config that
89-
reliably plays referrer-restricted videos) using **YouTube's own controls and
90-
native fullscreen**. Playback state is still bridged to `usePlayback` /
91-
`useVideoEvents`, and `play()/pause()/seek()` are forwarded to the player, so
92-
it fits the same API. Native (`type: 'url'`, the default) and YouTube sources
93-
are interchangeable. Requires `react-native-webview`.
94-
95-
> YouTube uses its own player UI (not the built-in `VideoControls`) and its own
96-
> fullscreen — a WebView can't be re-parented like the native engine, and the
97-
> embed's referrer restriction requires loading it directly. Native video
98-
> keeps the custom controls, seamless handoff and library fullscreen.
89+
YouTube runs on a **native, re-parentable WebView** that is a second engine
90+
inside the singleton core — moved between surfaces exactly like the native
91+
player view. So YouTube gets the **same built-in `VideoControls`, the same
92+
fullscreen host, and seamless inline→fullscreen handoff with no reload**, just
93+
like native video. It loads the embed with a `youtube.com` referrer (which is
94+
what plays referrer-restricted videos) and hides YouTube's own UI; state and
95+
commands bridge through the IFrame API to the standard `usePlayback` /
96+
`useVideoEvents` / `play()/pause()/seek()`. `type: 'url'` (default) and
97+
`type: 'youtube'` are fully interchangeable.
9998

10099
**3. Open a detail screen with the same video** — because the `id` matches,
101100
the engine is untouched and playback continues from the exact frame:

android/src/main/java/com/auvideo/AuVideoModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class AuVideoModule(reactContext: ReactApplicationContext) :
7373
return SourceSpec(
7474
id = id,
7575
uri = uri,
76+
type = map.getString("type") ?: "url",
7677
headers = headers,
7778
title = map.getString("title"),
7879
artist = map.getString("artist"),

0 commit comments

Comments
 (0)