react-native-media3-player 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +211 -46
- package/android/build.gradle +16 -3
- package/android/src/main/java/com/rnmedia3playerdemo/Media3PlayerView.kt +36 -7
- package/android/src/main/java/com/rnmedia3playerdemo/Media3PlayerViewManager.kt +24 -3
- package/package.json +1 -1
- package/src/Media3PlayerNativeComponent.ts +17 -1
package/README.md
CHANGED
|
@@ -5,14 +5,16 @@
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
8
|
+
|
|
9
|
+
- [Installation](#installation)
|
|
10
|
+
- [Usage](#usage)
|
|
11
|
+
- [Props](#props)
|
|
12
|
+
- [DRM Support (Widevine)](#drm-support-widevine)
|
|
13
|
+
- [Events](#events)
|
|
14
|
+
- [TypeScript Support](#typescript-support)
|
|
15
|
+
- [Examples](#examples)
|
|
16
|
+
- [Screenshots](#screenshots)
|
|
17
|
+
- [Contributing](#contributing)
|
|
16
18
|
- [License](#license)
|
|
17
19
|
|
|
18
20
|
---
|
|
@@ -20,38 +22,85 @@
|
|
|
20
22
|
## Installation
|
|
21
23
|
|
|
22
24
|
**Install via npm:**
|
|
25
|
+
|
|
23
26
|
```bash
|
|
24
27
|
npm install react-native-media3-player
|
|
25
28
|
```
|
|
26
29
|
|
|
27
30
|
**Or yarn:**
|
|
31
|
+
|
|
28
32
|
```bash
|
|
29
33
|
yarn add react-native-media3-player
|
|
30
34
|
```
|
|
31
35
|
|
|
32
|
-
> Requires **React Native >= 0.70**
|
|
36
|
+
> Requires **React Native >= 0.70**
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
**Note:** To use a specific Media3 version, add or update the following in your **android/build.gradle** (Project-level) file:
|
|
41
|
+
|
|
42
|
+
```groovy
|
|
43
|
+
buildscript {
|
|
44
|
+
ext {
|
|
45
|
+
media3Version = "1.4.1" // Set your desired Media3 version
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Be sure to sync your project after making this change.
|
|
33
51
|
|
|
34
52
|
---
|
|
35
53
|
|
|
36
54
|
## Usage
|
|
37
55
|
|
|
56
|
+
**Basic (non-DRM):**
|
|
57
|
+
|
|
38
58
|
```jsx
|
|
39
59
|
import React from 'react';
|
|
40
|
-
import {
|
|
60
|
+
import {View} from 'react-native';
|
|
41
61
|
import Media3Player from 'react-native-media3-player';
|
|
42
62
|
|
|
43
63
|
export default function App() {
|
|
44
64
|
return (
|
|
45
|
-
<View style={{
|
|
65
|
+
<View style={{flex: 1}}>
|
|
46
66
|
<Media3Player
|
|
47
|
-
style={{
|
|
48
|
-
source={{
|
|
67
|
+
style={{width: '100%', height: 250}}
|
|
68
|
+
source={{uri: 'https://example.com/video.mp4'}}
|
|
49
69
|
autoplay={true}
|
|
50
70
|
play={true}
|
|
51
71
|
mute={false}
|
|
52
72
|
onReady={() => console.log('Player is ready')}
|
|
53
73
|
onEnd={() => console.log('Video ended')}
|
|
54
|
-
onError={
|
|
74
|
+
onError={error => console.log('Player error:', error.message)}
|
|
75
|
+
/>
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**DRM-protected content (Widevine):**
|
|
82
|
+
|
|
83
|
+
```jsx
|
|
84
|
+
import React from 'react';
|
|
85
|
+
import {View} from 'react-native';
|
|
86
|
+
import Media3Player from 'react-native-media3-player';
|
|
87
|
+
|
|
88
|
+
export default function App() {
|
|
89
|
+
return (
|
|
90
|
+
<View style={{flex: 1}}>
|
|
91
|
+
<Media3Player
|
|
92
|
+
style={{width: '100%', height: 250}}
|
|
93
|
+
source={{
|
|
94
|
+
uri: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd',
|
|
95
|
+
drm: {
|
|
96
|
+
licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth',
|
|
97
|
+
},
|
|
98
|
+
}}
|
|
99
|
+
autoplay={true}
|
|
100
|
+
play={true}
|
|
101
|
+
onReady={() => console.log('Player is ready')}
|
|
102
|
+
onEnd={() => console.log('Video ended')}
|
|
103
|
+
onError={error => console.log('Player error:', error.message)}
|
|
55
104
|
/>
|
|
56
105
|
</View>
|
|
57
106
|
);
|
|
@@ -62,23 +111,87 @@ export default function App() {
|
|
|
62
111
|
|
|
63
112
|
## Props
|
|
64
113
|
|
|
65
|
-
| Prop | Type
|
|
66
|
-
|
|
67
|
-
| `source` | `
|
|
68
|
-
| `autoplay` | `boolean`
|
|
69
|
-
| `play` | `boolean`
|
|
70
|
-
| `mute` | `boolean`
|
|
71
|
-
| `style` | `ViewStyle` or `ViewStyle[]` | `{ width: '100%', height: 250 }` | Styling for the player container.
|
|
114
|
+
| Prop | Type | Default | Description |
|
|
115
|
+
| ---------- | ---------------------------- | -------------------------------- | ------------------------------------------------------------------------ |
|
|
116
|
+
| `source` | `Source` | required | Video source object. Must include a valid `uri`. Supports optional `drm` config. |
|
|
117
|
+
| `autoplay` | `boolean` | `false` | Automatically start playback when the video is ready. |
|
|
118
|
+
| `play` | `boolean` | `false` | Controls whether the player is playing. Overrides autoplay. |
|
|
119
|
+
| `mute` | `boolean` | `false` | Mutes or unmutes the video. |
|
|
120
|
+
| `style` | `ViewStyle` or `ViewStyle[]` | `{ width: '100%', height: 250 }` | Styling for the player container. |
|
|
121
|
+
|
|
122
|
+
### `Source` Object
|
|
123
|
+
|
|
124
|
+
| Property | Type | Required | Description |
|
|
125
|
+
| -------- | ----------- | -------- | ---------------------------------------------------- |
|
|
126
|
+
| `uri` | `string` | Yes | The URI of the media to play (MP4, DASH, HLS, etc.). |
|
|
127
|
+
| `drm` | `DRMConfig` | No | DRM configuration for protected content. |
|
|
128
|
+
|
|
129
|
+
### `DRMConfig` Object
|
|
130
|
+
|
|
131
|
+
| Property | Type | Required | Description |
|
|
132
|
+
| ------------ | --------------------------------- | -------- | ----------------------------------------------------- |
|
|
133
|
+
| `licenseUrl` | `string` | Yes | The Widevine license server URL. |
|
|
134
|
+
| `headers` | `Array<{ key: string, value: string }>` | No | Custom headers to include in the DRM license request. |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## DRM Support (Widevine)
|
|
139
|
+
|
|
140
|
+
This library supports **Widevine DRM** for playing protected DASH streams on Android. To enable DRM, pass a `drm` object inside the `source` prop.
|
|
141
|
+
|
|
142
|
+
### Basic DRM Playback
|
|
143
|
+
|
|
144
|
+
```jsx
|
|
145
|
+
<Media3Player
|
|
146
|
+
source={{
|
|
147
|
+
uri: 'https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd',
|
|
148
|
+
drm: {
|
|
149
|
+
licenseUrl: 'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
|
|
150
|
+
},
|
|
151
|
+
}}
|
|
152
|
+
autoplay
|
|
153
|
+
play
|
|
154
|
+
/>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### DRM with Custom License Headers
|
|
158
|
+
|
|
159
|
+
Some license servers require authentication tokens or custom headers. Pass them as an array of `{ key, value }` objects:
|
|
160
|
+
|
|
161
|
+
```jsx
|
|
162
|
+
<Media3Player
|
|
163
|
+
source={{
|
|
164
|
+
uri: 'https://example.com/protected-stream/manifest.mpd',
|
|
165
|
+
drm: {
|
|
166
|
+
licenseUrl: 'https://license.example.com/widevine',
|
|
167
|
+
headers: [
|
|
168
|
+
{key: 'Authorization', value: 'Bearer <your-token>'},
|
|
169
|
+
{key: 'X-Custom-Header', value: 'custom-value'},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
}}
|
|
173
|
+
autoplay
|
|
174
|
+
play
|
|
175
|
+
onError={e => console.error('DRM error:', e.message)}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Notes
|
|
180
|
+
|
|
181
|
+
- DRM is currently supported on **Android only** (Widevine L1/L3 depending on device).
|
|
182
|
+
- The `source.uri` should point to a DASH (`.mpd`) stream encrypted with Widevine.
|
|
183
|
+
- Multi-session DRM is enabled by default for streams that require it.
|
|
184
|
+
- If the license request fails, the `onError` callback will fire with the error details.
|
|
72
185
|
|
|
73
186
|
---
|
|
74
187
|
|
|
75
188
|
## Events
|
|
76
189
|
|
|
77
|
-
| Event
|
|
78
|
-
|
|
79
|
-
| `onReady`
|
|
80
|
-
| `onEnd`
|
|
81
|
-
| `onError`
|
|
190
|
+
| Event | Callback Signature | Description |
|
|
191
|
+
| --------- | -------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
192
|
+
| `onReady` | `() => void` | Fired when the player is ready to play. |
|
|
193
|
+
| `onEnd` | `() => void` | Fired when the video reaches the end. |
|
|
194
|
+
| `onError` | `(error: { message: string }) => void` | Fired when the player encounters an error. Error object includes a `message` property. |
|
|
82
195
|
|
|
83
196
|
---
|
|
84
197
|
|
|
@@ -88,18 +201,38 @@ This library includes TypeScript definitions. Example:
|
|
|
88
201
|
|
|
89
202
|
```ts
|
|
90
203
|
import React from 'react';
|
|
91
|
-
import {
|
|
92
|
-
import Media3Player, {
|
|
204
|
+
import {ViewStyle} from 'react-native';
|
|
205
|
+
import Media3Player, {Media3PlayerProps} from 'react-native-media3-player';
|
|
93
206
|
|
|
94
207
|
const props: Media3PlayerProps = {
|
|
95
|
-
source: {
|
|
208
|
+
source: {uri: 'https://example.com/video.mp4'},
|
|
96
209
|
autoplay: true,
|
|
97
210
|
play: true,
|
|
98
211
|
mute: false,
|
|
99
|
-
style: {
|
|
212
|
+
style: {width: '100%', height: 250},
|
|
100
213
|
onReady: () => console.log('Ready'),
|
|
101
214
|
onEnd: () => console.log('End'),
|
|
102
|
-
onError:
|
|
215
|
+
onError: err => console.log(err.message),
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**With DRM:**
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
const drmProps: Media3PlayerProps = {
|
|
223
|
+
source: {
|
|
224
|
+
uri: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd',
|
|
225
|
+
drm: {
|
|
226
|
+
licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth',
|
|
227
|
+
headers: [
|
|
228
|
+
{key: 'Authorization', value: 'Bearer my-token'},
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
autoplay: true,
|
|
233
|
+
play: true,
|
|
234
|
+
style: {width: '100%', height: 250},
|
|
235
|
+
onError: err => console.log('DRM Error:', err.message),
|
|
103
236
|
};
|
|
104
237
|
```
|
|
105
238
|
|
|
@@ -108,26 +241,59 @@ const props: Media3PlayerProps = {
|
|
|
108
241
|
## Examples
|
|
109
242
|
|
|
110
243
|
**Basic Player:**
|
|
244
|
+
|
|
111
245
|
```jsx
|
|
112
|
-
<Media3Player source={{
|
|
246
|
+
<Media3Player source={{uri: 'https://example.com/video.mp4'}} />
|
|
113
247
|
```
|
|
114
248
|
|
|
115
249
|
**Autoplay & Mute:**
|
|
250
|
+
|
|
116
251
|
```jsx
|
|
117
|
-
<Media3Player
|
|
118
|
-
source={{ uri: 'https://example.com/video.mp4' }}
|
|
119
|
-
autoplay
|
|
120
|
-
mute
|
|
121
|
-
/>
|
|
252
|
+
<Media3Player source={{uri: 'https://example.com/video.mp4'}} autoplay mute />
|
|
122
253
|
```
|
|
123
254
|
|
|
124
255
|
**Event Handling:**
|
|
256
|
+
|
|
125
257
|
```jsx
|
|
126
258
|
<Media3Player
|
|
127
|
-
source={{
|
|
259
|
+
source={{uri: 'https://example.com/video.mp4'}}
|
|
128
260
|
onReady={() => console.log('Ready')}
|
|
129
261
|
onEnd={() => console.log('End')}
|
|
130
|
-
onError={
|
|
262
|
+
onError={err => console.error(err.message)}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Widevine DRM Stream:**
|
|
267
|
+
|
|
268
|
+
```jsx
|
|
269
|
+
<Media3Player
|
|
270
|
+
source={{
|
|
271
|
+
uri: 'https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd',
|
|
272
|
+
drm: {
|
|
273
|
+
licenseUrl: 'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
|
|
274
|
+
},
|
|
275
|
+
}}
|
|
276
|
+
autoplay
|
|
277
|
+
play
|
|
278
|
+
/>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**DRM with License Headers:**
|
|
282
|
+
|
|
283
|
+
```jsx
|
|
284
|
+
<Media3Player
|
|
285
|
+
source={{
|
|
286
|
+
uri: 'https://example.com/protected/manifest.mpd',
|
|
287
|
+
drm: {
|
|
288
|
+
licenseUrl: 'https://license.example.com/widevine',
|
|
289
|
+
headers: [
|
|
290
|
+
{key: 'Authorization', value: 'Bearer my-token'},
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
}}
|
|
294
|
+
autoplay
|
|
295
|
+
play
|
|
296
|
+
onError={err => console.error('DRM Error:', err.message)}
|
|
131
297
|
/>
|
|
132
298
|
```
|
|
133
299
|
|
|
@@ -135,13 +301,13 @@ const props: Media3PlayerProps = {
|
|
|
135
301
|
|
|
136
302
|
## Contributing
|
|
137
303
|
|
|
138
|
-
We welcome contributions!
|
|
304
|
+
We welcome contributions!
|
|
139
305
|
|
|
140
|
-
1. Fork the repo
|
|
141
|
-
2. Create a branch (`git checkout -b feature/new-feature`)
|
|
142
|
-
3. Commit your changes (`git commit -m 'Add feature'`)
|
|
143
|
-
4. Push to the branch (`git push origin feature/new-feature`)
|
|
144
|
-
5. Open a Pull Request
|
|
306
|
+
1. Fork the repo
|
|
307
|
+
2. Create a branch (`git checkout -b feature/new-feature`)
|
|
308
|
+
3. Commit your changes (`git commit -m 'Add feature'`)
|
|
309
|
+
4. Push to the branch (`git push origin feature/new-feature`)
|
|
310
|
+
5. Open a Pull Request
|
|
145
311
|
|
|
146
312
|
> Please follow [Semantic Versioning](https://semver.org/) for commits.
|
|
147
313
|
|
|
@@ -150,4 +316,3 @@ We welcome contributions!
|
|
|
150
316
|
## License
|
|
151
317
|
|
|
152
318
|
MIT © [Mohammad Rehan](https://github.com/mdRehan991)
|
|
153
|
-
|
package/android/build.gradle
CHANGED
|
@@ -5,6 +5,11 @@ apply plugin: "org.jetbrains.kotlin.android"
|
|
|
5
5
|
// Apply the React Native plugin to enable React Native integration
|
|
6
6
|
apply plugin: "com.facebook.react"
|
|
7
7
|
|
|
8
|
+
// Use app-defined version if available, otherwise fallback
|
|
9
|
+
def media3Version = rootProject.ext.has("media3Version")
|
|
10
|
+
? rootProject.ext.media3Version
|
|
11
|
+
: "1.4.1"
|
|
12
|
+
|
|
8
13
|
android {
|
|
9
14
|
// Set the namespace for the generated R class and manifest
|
|
10
15
|
namespace "com.rnmedia3playerdemo"
|
|
@@ -46,9 +51,17 @@ dependencies {
|
|
|
46
51
|
implementation "org.jetbrains.kotlin:kotlin-stdlib"
|
|
47
52
|
|
|
48
53
|
// AndroidX Media3 ExoPlayer, UI components, and Common classes
|
|
49
|
-
implementation "androidx.media3:media3-exoplayer
|
|
50
|
-
implementation "androidx.media3:media3-ui
|
|
51
|
-
implementation "androidx.media3:media3-common
|
|
54
|
+
implementation "androidx.media3:media3-exoplayer:$media3Version"
|
|
55
|
+
implementation "androidx.media3:media3-ui:$media3Version"
|
|
56
|
+
implementation "androidx.media3:media3-common:$media3Version"
|
|
57
|
+
|
|
58
|
+
// streaming formats
|
|
59
|
+
implementation "androidx.media3:media3-exoplayer-dash:$media3Version"
|
|
60
|
+
implementation "androidx.media3:media3-exoplayer-hls:$media3Version"
|
|
61
|
+
implementation "androidx.media3:media3-exoplayer-smoothstreaming:$media3Version"
|
|
62
|
+
|
|
63
|
+
// OkHttp data source for Media3 (DRM/auth/advanced networking)
|
|
64
|
+
implementation "androidx.media3:media3-datasource-okhttp:$media3Version"
|
|
52
65
|
|
|
53
66
|
// Android core utilities and extensions (KTX)
|
|
54
67
|
implementation "androidx.core:core-ktx:1.13.1"
|
|
@@ -14,6 +14,7 @@ import com.facebook.react.bridge.ReactContext
|
|
|
14
14
|
import com.facebook.react.bridge.WritableMap
|
|
15
15
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
16
16
|
import com.facebook.react.uimanager.events.Event
|
|
17
|
+
import androidx.media3.common.C
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Custom view that wraps ExoPlayer and PlayerView, integrating with React Native.
|
|
@@ -83,19 +84,47 @@ class Media3PlayerView(context: Context) : FrameLayout(context) {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
|
-
* Sets the video source
|
|
87
|
-
*
|
|
87
|
+
* Sets the video source (with optional DRM support) and prepares the player.
|
|
88
|
+
* Called from the ViewManager when the JS "source" prop changes.
|
|
89
|
+
*
|
|
90
|
+
* @param uriString The URI of the media source to play.
|
|
91
|
+
* @param licenseUrl If provided, enables DRM playback with this license URL.
|
|
92
|
+
* @param headers Optional headers to add to DRM license requests.
|
|
88
93
|
*/
|
|
89
|
-
fun setSource(
|
|
94
|
+
fun setSource(
|
|
95
|
+
uriString: String?,
|
|
96
|
+
licenseUrl: String?,
|
|
97
|
+
headers: Map<String, String>?
|
|
98
|
+
) {
|
|
99
|
+
// Return early if no valid URI is provided
|
|
90
100
|
if (uriString.isNullOrEmpty()) return
|
|
91
101
|
sourceUri = uriString
|
|
92
102
|
|
|
93
|
-
// Ensure
|
|
103
|
+
// Ensure the ExoPlayer instance is initialized before use
|
|
94
104
|
initializePlayer()
|
|
95
105
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
val uri = Uri.parse(uriString)
|
|
107
|
+
// Build the MediaItem, adding DRM configuration if a license URL is given
|
|
108
|
+
val mediaItem =
|
|
109
|
+
if (!licenseUrl.isNullOrEmpty()) {
|
|
110
|
+
val drmBuilder = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
|
|
111
|
+
.setLicenseUri(licenseUrl) // set the license URL
|
|
112
|
+
.setMultiSession(true) // allow multiple DRM sessions if the stream requires them
|
|
113
|
+
|
|
114
|
+
headers?.let {
|
|
115
|
+
drmBuilder.setLicenseRequestHeaders(it)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
MediaItem.Builder()
|
|
119
|
+
.setUri(uri)
|
|
120
|
+
.setDrmConfiguration(drmBuilder.build())
|
|
121
|
+
.build()
|
|
122
|
+
} else {
|
|
123
|
+
// No DRM: simple MediaItem from URI
|
|
124
|
+
MediaItem.fromUri(uri)
|
|
125
|
+
}
|
|
126
|
+
// Set the media item on the player and prepare for playback
|
|
127
|
+
exoPlayer?.setMediaItem(mediaItem)
|
|
99
128
|
exoPlayer?.prepare()
|
|
100
129
|
}
|
|
101
130
|
|
|
@@ -45,14 +45,35 @@ class Media3PlayerViewManager :
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
48
|
+
* Handles the "source" prop for Media3PlayerView.
|
|
49
|
+
* Extracts the "uri", optional DRM license URL, and headers from the ReadableMap and forwards
|
|
50
|
+
* them to the view for loading the media source and DRM configuration.
|
|
50
51
|
*/
|
|
51
52
|
@ReactProp(name = "source")
|
|
52
53
|
override fun setSource(view: Media3PlayerView, source: ReadableMap?) {
|
|
53
54
|
val uri = source?.getString("uri")
|
|
55
|
+
var licenseUrl: String? = null
|
|
56
|
+
var headers: Map<String, String>? = null
|
|
57
|
+
val drmMap = source?.getMap("drm")
|
|
58
|
+
|
|
59
|
+
if (drmMap != null) {
|
|
60
|
+
licenseUrl = drmMap.getString("licenseUrl")
|
|
61
|
+
val headersArray = drmMap.getArray("headers")
|
|
62
|
+
if (headersArray != null) {
|
|
63
|
+
val map = mutableMapOf<String, String>()
|
|
64
|
+
for (i in 0 until headersArray.size()) {
|
|
65
|
+
val entry = headersArray.getMap(i)
|
|
66
|
+
val key = entry?.getString("key")
|
|
67
|
+
val value = entry?.getString("value")
|
|
68
|
+
if (key != null && value != null) {
|
|
69
|
+
map[key] = value
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
headers = map
|
|
73
|
+
}
|
|
74
|
+
}
|
|
54
75
|
if (!uri.isNullOrEmpty()) {
|
|
55
|
-
view.setSource(uri)
|
|
76
|
+
view.setSource(uri, licenseUrl, headers)
|
|
56
77
|
}
|
|
57
78
|
}
|
|
58
79
|
|
package/package.json
CHANGED
|
@@ -5,6 +5,22 @@ import type {DirectEventHandler} from 'react-native/Libraries/Types/CodegenTypes
|
|
|
5
5
|
// Import codegenNativeComponent to register the native UI component for use in React Native
|
|
6
6
|
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
7
7
|
|
|
8
|
+
type HeaderEntry = Readonly<{
|
|
9
|
+
key: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
13
|
+
type DRMConfig = Readonly<{
|
|
14
|
+
licenseUrl: string;
|
|
15
|
+
headers?: ReadonlyArray<HeaderEntry>;
|
|
16
|
+
}>;
|
|
17
|
+
// Source defines the media source for the player component.
|
|
18
|
+
// - uri: The URI of the media to be played (required).
|
|
19
|
+
// - drm: (Optional) DRM configuration for protected content.
|
|
20
|
+
type Source = Readonly<{
|
|
21
|
+
uri: string;
|
|
22
|
+
drm?: DRMConfig;
|
|
23
|
+
}>;
|
|
8
24
|
// Event type emitted when the player is ready
|
|
9
25
|
type OnReadyEvent = Readonly<{}>;
|
|
10
26
|
// Event type emitted when playback reaches the end
|
|
@@ -17,7 +33,7 @@ type OnErrorEvent = Readonly<{
|
|
|
17
33
|
// Props supported by the native Media3PlayerView component
|
|
18
34
|
export interface NativeProps extends ViewProps {
|
|
19
35
|
// Source URI for the media to play
|
|
20
|
-
source?:
|
|
36
|
+
source?: Source;
|
|
21
37
|
// Whether playback should start automatically when ready
|
|
22
38
|
autoplay?: boolean;
|
|
23
39
|
// Whether playback should currently be running (true = play, false = pause)
|