Skip to content

Commit 5fa77c4

Browse files
zoriyamoskalakamil
andauthored
Add react-native-web support (#3958)
Co-authored-by: Kamil Moskała <[email protected]>
1 parent d453002 commit 5fa77c4

24 files changed

+608
-36
lines changed

docs/bun.lockb

0 Bytes
Binary file not shown.

docs/pages/component/events.mdx

+7-4
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Note: On Android, you must set the [reportBandwidth](#reportbandwidth) prop to e
103103

104104
### `onBuffer`
105105

106-
<PlatformsList types={['Android', 'iOS']} />
106+
<PlatformsList types={['Android', 'iOS', 'web']} />
107107

108108
Callback function that is called when the player buffers.
109109

@@ -219,6 +219,9 @@ Payload: none
219219

220220
Callback function that is called when the media is loaded and ready to play.
221221

222+
223+
NOTE: tracks (`audioTracks`, `textTracks` & `videoTracks`) are not available on the web.
224+
222225
Payload:
223226

224227
| Property | Type | Description |
@@ -292,7 +295,7 @@ Example:
292295

293296
### `onPlaybackStateChanged`
294297

295-
<PlatformsList types={['Android', 'iOS', 'visionOS']} />
298+
<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />
296299

297300
Callback function that is called when the playback state changes.
298301

@@ -463,7 +466,7 @@ Payload: none
463466

464467
### `onSeek`
465468

466-
<PlatformsList types={['Android', 'iOS', 'Windows UWP']} />
469+
<PlatformsList types={['Android', 'iOS', 'Windows UWP', 'web']} />
467470

468471
Callback function that is called when a seek completes.
469472

@@ -604,7 +607,7 @@ Example:
604607

605608
### `onVolumeChange`
606609

607-
<PlatformsList types={['Android', 'iOS', 'visionOS']} />
610+
<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />
608611

609612
Callback function that is called when the volume of player changes.
610613

docs/pages/component/methods.mdx

+15-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This page shows the list of available methods
66

77
### `dismissFullscreenPlayer`
88

9-
<PlatformsList types={['Android', 'iOS']} />
9+
<PlatformsList types={['Android', 'iOS', 'web']} />
1010

1111
`dismissFullscreenPlayer(): Promise<void>`
1212

@@ -17,15 +17,15 @@ Take the player out of fullscreen mode.
1717
1818
### `pause`
1919

20-
<PlatformsList types={['Android', 'iOS']} />
20+
<PlatformsList types={['Android', 'iOS', 'web']} />
2121

2222
`pause(): Promise<void>`
2323

2424
Pause the video.
2525

2626
### `presentFullscreenPlayer`
2727

28-
<PlatformsList types={['Android', 'iOS']} />
28+
<PlatformsList types={['Android', 'iOS', 'web']} />
2929

3030
`presentFullscreenPlayer(): Promise<void>`
3131

@@ -40,7 +40,7 @@ On Android, this puts the navigation controls in fullscreen mode. It is not a co
4040
4141
### `resume`
4242

43-
<PlatformsList types={['Android', 'iOS']} />
43+
<PlatformsList types={['Android', 'iOS', 'web']} />
4444

4545
`resume(): Promise<void>`
4646

@@ -100,15 +100,15 @@ tolerance is the max distance in milliseconds from the seconds position that's a
100100

101101
### `setVolume`
102102

103-
<PlatformsList types={['Android', 'iOS']} />
103+
<PlatformsList types={['Android', 'iOS', 'web']} />
104104

105105
`setVolume(value): Promise<void>`
106106

107107
This function will change the volume exactly like [volume](./props#volume) property. default value and range are the same then.
108108

109109
### `getCurrentPosition`
110110

111-
<PlatformsList types={['Android', 'iOS']} />
111+
<PlatformsList types={['Android', 'iOS', 'web']} />
112112

113113
`getCurrentPosition(): Promise<number>`
114114

@@ -127,7 +127,7 @@ Changing source with this function will overide source provided as props.
127127

128128
### `setFullScreen`
129129

130-
<PlatformsList types={['Android', 'iOS']} />
130+
<PlatformsList types={['Android', 'iOS', 'web']} />
131131

132132
`setFullScreen(fullscreen): Promise<void>`
133133

@@ -137,6 +137,13 @@ On iOS, this displays the video in a fullscreen view controller with controls.
137137

138138
On Android, this puts the navigation controls in fullscreen mode. It is not a complete fullscreen implementation, so you will still need to apply a style that makes the width and height match your screen dimensions to get a fullscreen video.
139139

140+
### `nativeHtmlVideoRef`
141+
142+
<PlatformsList types={['web']} />
143+
144+
A ref to the underlying html video element. This can be used if you need to integrate a 3d party, web only video library (like hls.js, shaka, video.js...).
145+
146+
140147
### Example Usage
141148

142149
```tsx
@@ -188,7 +195,7 @@ Possible values are:
188195

189196
### `isCodecSupported`
190197

191-
<PlatformsList types={['Android']} />
198+
<PlatformsList types={['Android', 'web']} />
192199

193200
Indicates whether the provided codec is supported level supported by device.
194201

docs/pages/component/props.mdx

+7-5
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ When playing an HLS live stream with a `EXT-X-PROGRAM-DATE-TIME` tag configured,
131131

132132
### `controls`
133133

134-
<PlatformsList types={['Android', 'iOS', 'visionOS']} />
134+
<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />
135135

136136
Determines whether to show player controls.
137137

@@ -300,7 +300,7 @@ Whether this video view should be focusable with a non-touch input device, eg. r
300300

301301
### `fullscreen`
302302

303-
<PlatformsList types={['Android', 'iOS', 'visionOS']} />
303+
<PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />
304304

305305
Controls whether the player enters fullscreen on play.
306306
See [presentFullscreenPlayer](#presentfullscreenplayer) for details.
@@ -316,7 +316,7 @@ If a preferred [fullscreenOrientation](#fullscreenorientation) is set, causes th
316316

317317
### `fullscreenOrientation`
318318

319-
<PlatformsList types={['iOS', 'visionOS']} />
319+
<PlatformsList types={['iOS', 'visionOS', 'web']} />
320320

321321
- **all (default)** -
322322
- **landscape**
@@ -709,6 +709,8 @@ The docs for this prop are incomplete and will be updated as each option is inve
709709

710710
> ⚠️ on iOS, you file name must not contain spaces eg. `my video.mp4` will not work, use `my-video.mp4` instead
711711

712+
<PlatformsList types={['Android', 'iOS', 'visionOS', 'Windows UWP']} />
713+
712714
Example:
713715

714716
Pass directly the asset to play (deprecated)
@@ -820,7 +822,7 @@ Example:
820822

821823
#### Start playback at a specific point in time
822824

823-
<PlatformsList types={['Android', 'iOS']} />
825+
<PlatformsList types={['Android', 'iOS', 'web']} />
824826

825827
Provide an optional `startPosition` for video. Value is in milliseconds. If the `cropStart` prop is applied, it will be applied from that point forward.
826828
(If it is negative or undefined or null, it is ignored)
@@ -1048,7 +1050,7 @@ textTracks={[
10481050

10491051
### `showNotificationControls`
10501052

1051-
<PlatformsList types={['Android', 'iOS']} />
1053+
<PlatformsList types={['Android', 'iOS', 'web']} />
10521054

10531055
Controls whether to show media controls in the notification area.
10541056
For Android each Video component will have its own notification controls and for iOS only one notification control will be shown for the last Active Video component.

docs/pages/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ It allows to stream video files (m3u, mpd, mp4, ...) inside your react native ap
88
- Exoplayer for android
99
- AVplayer for iOS, tvOS and visionOS
1010
- Windows UWP for windows
11+
- HTML5 for web
1112
- Trick mode support
1213
- Subtitles (embeded or side loaded)
1314
- DRM support

docs/pages/installation.md

+9
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,12 @@ Select RCTVideo-tvOS
181181
Run `pod install` in the `visionos` directory of your project
182182

183183
</details>
184+
185+
<details>
186+
<summary>web</summary>
187+
188+
Nothing to do, everything should work out of the box.
189+
190+
Note that only basic video support is present, no hls/dash or ads/drm for now.
191+
192+
</details>

examples/README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This directory contains examples for `react-native-video` - this is a guide that
66

77
- **[`bare`](#bare)** - Main example ([react-native-test-app](https://github.com/microsoft/react-native-test-app) - bare react-native app) that you can run on: iOS, Android, Windows, visionOS
88

9-
- **[`expo`](#expo)** - Expo example that you can run on: iOS, Android, tvOS, web (support coming soon)
9+
- **[`expo`](#expo)** - Expo example that you can run on: iOS, Android, tvOS, web
1010

1111
### Updating Examples Content
1212

@@ -151,7 +151,9 @@ cd examples/expo && yarn install
151151
> Setup for android is not complete yet. Please use bare app for android testing.
152152
153153
- For Web:
154-
Support for web is coming soon.
154+
```bash
155+
yarn web
156+
```
155157
156158
If Metro Bundler is not running (or it did not start), you can start it by running:
157159

examples/bare/src/constants/general.ts

+8
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ export const srcAllPlatformList = [
7878
description: 'another bunny (can be saved)',
7979
uri: 'https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4',
8080
headers: {referer: 'www.github.com', 'User-Agent': 'react.native.video'},
81+
metadata: {
82+
title: 'Custom Title',
83+
subtitle: 'Custom Subtitle',
84+
artist: 'Custom Artist',
85+
description: 'Custom Description',
86+
imageUri:
87+
'https://pbs.twimg.com/profile_images/1498641868397191170/6qW2XkuI_400x400.png',
88+
},
8189
},
8290
{
8391
description: 'sintel with subtitles',

examples/bare/src/styles.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {StyleSheet} from 'react-native';
1+
import {Platform, StyleSheet} from 'react-native';
22

33
const styles = StyleSheet.create({
44
container: {
@@ -63,6 +63,7 @@ const styles = StyleSheet.create({
6363
borderRadius: 4,
6464
overflow: 'hidden',
6565
paddingBottom: 10,
66+
paddingTop: Platform.OS === 'web' ? 25 : 0,
6667
},
6768
rateControl: {
6869
flex: 1,
@@ -146,7 +147,7 @@ const styles = StyleSheet.create({
146147
},
147148
picker: {
148149
flex: 1,
149-
color: 'white',
150+
color: Platform.OS === 'web' ? 'black' : 'white',
150151
flexDirection: 'row',
151152
justifyContent: 'center',
152153
width: 100,

examples/expo/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
"update-src": "echo 'Updating src from ../bare/src' && rm -r ./src && cp -r ../bare/src ./src && echo 'Updated src from ../bare/src'"
1616
},
1717
"dependencies": {
18+
"@expo/metro-runtime": "^3.2.3",
1819
"@react-native-picker/picker": "2.8.1",
1920
"expo": "~51.0.31",
2021
"expo-splash-screen": "~0.27.5",
2122
"expo-status-bar": "~1.12.1",
2223
"react": "18.2.0",
2324
"react-dom": "18.2.0",
24-
"react-native": "npm:react-native-tvos@~0.74.5-0"
25+
"react-native": "npm:react-native-tvos@~0.74.5-0",
26+
"react-native-web": "^0.19.13"
2527
},
2628
"devDependencies": {
2729
"@babel/core": "^7.24.0",

examples/expo/src/constants/general.ts

+8
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ export const srcAllPlatformList = [
7878
description: 'another bunny (can be saved)',
7979
uri: 'https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4',
8080
headers: {referer: 'www.github.com', 'User-Agent': 'react.native.video'},
81+
metadata: {
82+
title: 'Custom Title',
83+
subtitle: 'Custom Subtitle',
84+
artist: 'Custom Artist',
85+
description: 'Custom Description',
86+
imageUri:
87+
'https://pbs.twimg.com/profile_images/1498641868397191170/6qW2XkuI_400x400.png',
88+
},
8189
},
8290
{
8391
description: 'sintel with subtitles',

examples/expo/src/styles.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {StyleSheet} from 'react-native';
1+
import {Platform, StyleSheet} from 'react-native';
22

33
const styles = StyleSheet.create({
44
container: {
@@ -63,6 +63,7 @@ const styles = StyleSheet.create({
6363
borderRadius: 4,
6464
overflow: 'hidden',
6565
paddingBottom: 10,
66+
paddingTop: Platform.OS === 'web' ? 25 : 0,
6667
},
6768
rateControl: {
6869
flex: 1,
@@ -146,7 +147,7 @@ const styles = StyleSheet.create({
146147
},
147148
picker: {
148149
flex: 1,
149-
color: 'white',
150+
color: Platform.OS === 'web' ? 'black' : 'white',
150151
flexDirection: 'row',
151152
justifyContent: 'center',
152153
width: 100,

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "6.7.0",
44
"description": "A <Video /> element for react-native",
55
"main": "lib/index",
6-
"source": "src/index",
6+
"source": "src/index.ts",
77
"react-native": "src/index",
88
"license": "MIT",
99
"author": "Community Contributors",

shell.nix

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{pkgs ? import <nixpkgs> {}}:
2+
pkgs.mkShell {
3+
packages = with pkgs; [
4+
nodejs-18_x
5+
nodePackages.yarn
6+
bun
7+
eslint_d
8+
prettierd
9+
jdk11
10+
(jdt-language-server.override { jdk = jdk11; })
11+
];
12+
}
13+

src/Video.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ import {
4545
resolveAssetSourceForVideo,
4646
} from './utils';
4747
import NativeVideoManager from './specs/NativeVideoManager';
48-
import type {VideoSaveData} from './specs/NativeVideoManager';
49-
import {CmcdMode, ViewType} from './types';
48+
import {ViewType, type VideoSaveData, CmcdMode} from './types';
5049
import type {
5150
OnLoadData,
5251
OnTextTracksData,

0 commit comments

Comments
 (0)