mirror of
https://github.com/zoriya/react-native-video.git
synced 2026-08-16 02:56:22 +00:00
212 lines
5.8 KiB
Plaintext
212 lines
5.8 KiB
Plaintext
---
|
||
sidebar_position: 4
|
||
title: DRM
|
||
description: React Native Video DRM Integration
|
||
---
|
||
import PlatformsList from "@site/src/components/PlatformsList/PlatformsList.tsx";
|
||
|
||
# DRM
|
||
|
||
## DRM Example
|
||
|
||
We provide a sample implementation in the [example app](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/common/DRMExample.tsx) demonstrating how to use DRM with `react-native-video`. You’ll need a valid token—visit [our site](https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=text) to obtain a **free 24-hour token**.
|
||
|
||
## DRM Offline
|
||
|
||
If you need DRM-protected content available offline, our [Offline Video SDK](https://www.thewidlarzgroup.com/offline-video-sdk/?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=offline-video-sdk-link) enables downloading, storing, and managing streams with and without DRM. It also handles many edge cases you may encounter over time.
|
||
|
||
### Prerequisites:
|
||
|
||
- Use `react-native-video` v6 or v7. If you're still on v5 or lower, [contact us](https://www.thewidlarzgroup.com/?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=upgrade-contact#Contact) for assistance.
|
||
|
||
> Supporting our software kits helps maintain this open-source project. Thank you!
|
||
|
||
## Providing DRM Data (Tested with HTTP/HTTPS Assets)
|
||
|
||
You can configure DRM playback by providing a DRM object with the following properties. This feature disables the use of `TextureView` on Android.
|
||
|
||
### DRM Properties
|
||
|
||
### `base64Certificate`
|
||
|
||
<PlatformsList types={["iOS", "visionOS"]} />
|
||
|
||
**Type:** boolean
|
||
**Default:** `false`
|
||
|
||
Indicates whether the certificate URL returns data in Base64 format.
|
||
|
||
### `certificateUrl`
|
||
|
||
<PlatformsList types={["iOS", "visionOS"]} />
|
||
|
||
**Type:** string
|
||
**Default:** `undefined`
|
||
|
||
The URL used to fetch a valid certificate for FairPlay.
|
||
|
||
### `getLicense`
|
||
|
||
<PlatformsList types={["iOS", "visionOS"]} />
|
||
|
||
**Type:** function
|
||
**Default:** `undefined`
|
||
|
||
Instead of setting `licenseServer`, you can manually acquire the license in JavaScript and send the result to the native module for FairPlay DRM configuration.
|
||
|
||
The following parameters are available in `getLicense`:
|
||
|
||
- `contentId`: The content ID from the DRM object or `loadingRequest.request.url?.host`
|
||
- `loadedLicenseUrl`: The URL retrieved from `loadingRequest.request.URL.absoluteString`, starting with `skd://` or `clearkey://`
|
||
- `licenseServer`: The URL passed in the DRM object
|
||
- `spcString`: The SPC used for DRM validation
|
||
|
||
You should return a Base64-encoded CKC response, either directly or as a `Promise`.
|
||
|
||
#### Example:
|
||
|
||
```js
|
||
getLicense: (spcString, contentId, licenseUrl, loadedLicenseUrl) => {
|
||
const base64spc = Base64.encode(spcString);
|
||
const formData = new FormData();
|
||
formData.append("spc", base64spc);
|
||
return fetch(`https://license.pallycon.com/ri/licenseManager.do`, {
|
||
method: "POST",
|
||
headers: {
|
||
"pallycon-customdata-v2": "your-custom-header",
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: formData,
|
||
})
|
||
.then((response) => response.text())
|
||
.then((response) => response)
|
||
.catch((error) => console.error("Error", error));
|
||
};
|
||
```
|
||
|
||
### `contentId`
|
||
|
||
<PlatformsList types={["iOS", "visionOS"]} />
|
||
|
||
**Type:** string
|
||
**Default:** `undefined`
|
||
|
||
Sets the content ID for the stream. If not specified, the system uses the host value from `loadingRequest.request.URL.host`.
|
||
|
||
### `headers`
|
||
|
||
<PlatformsList types={["Android", "iOS", "visionOS"]} />
|
||
|
||
**Type:** Object
|
||
**Default:** `undefined`
|
||
|
||
Custom headers for the license server request.
|
||
|
||
#### Example:
|
||
|
||
```js
|
||
drm: {
|
||
type: DRMType.WIDEVINE,
|
||
licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
|
||
headers: {
|
||
'X-AxDRM-Message': 'your-drm-header',
|
||
},
|
||
}
|
||
```
|
||
|
||
### `licenseServer`
|
||
|
||
<PlatformsList types={["Android", "iOS", "visionOS"]} />
|
||
|
||
**Type:** string
|
||
**Default:** `undefined`
|
||
|
||
The license server URL that authorizes protected content playback.
|
||
|
||
### `multiDrm`
|
||
|
||
<PlatformsList types={["Android"]} />
|
||
|
||
**Type:** boolean
|
||
**Default:** `false`
|
||
|
||
Indicates whether the DRM system should support key rotation. See [Android Developer Docs](https://developer.android.google.cn/media/media3/exoplayer/drm?hl=en#key-rotation) for more details.
|
||
|
||
### `type`
|
||
|
||
<PlatformsList types={["Android", "iOS"]} />
|
||
|
||
**Type:** DRMType
|
||
**Default:** `undefined`
|
||
|
||
Defines the DRM type:
|
||
|
||
- **Android:** `DRMType.WIDEVINE`, `DRMType.PLAYREADY`, `DRMType.CLEARKEY`
|
||
- **iOS:** `DRMType.FAIRPLAY`
|
||
|
||
### `localSourceEncryptionKeyScheme`
|
||
|
||
<PlatformsList types={["iOS", "visionOS"]} />
|
||
|
||
**Type:** string
|
||
|
||
Sets the URL scheme for stream encryption keys used in local assets.
|
||
|
||
#### Example:
|
||
|
||
```js
|
||
localSourceEncryptionKeyScheme = "my-offline-key";
|
||
```
|
||
|
||
## Common Usage Scenarios
|
||
|
||
### Sending Cookies to the License Server
|
||
|
||
You can send cookies using the `headers` prop.
|
||
|
||
#### Example:
|
||
|
||
```js
|
||
drm: {
|
||
type: DRMType.WIDEVINE,
|
||
licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
|
||
headers: {
|
||
'Cookie': 'PHPSESSID=your-session-id; csrftoken=mytoken; _gat=1; foo=bar'
|
||
},
|
||
}
|
||
```
|
||
|
||
### Custom License Acquisition (iOS Only)
|
||
|
||
#### Example:
|
||
|
||
```js
|
||
drm: {
|
||
type: DRMType.FAIRPLAY,
|
||
getLicense: (spcString) => {
|
||
const base64spc = Base64.encode(spcString);
|
||
return fetch('YOUR_LICENSE_SERVER_URL', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
Accept: 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
getFairplayLicense: {
|
||
foo: 'bar',
|
||
spcMessage: base64spc,
|
||
}
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then((response) => {
|
||
if (response?.getFairplayLicenseResponse?.ckcResponse) {
|
||
return response.getFairplayLicenseResponse.ckcResponse;
|
||
}
|
||
throw new Error('No valid response');
|
||
})
|
||
.catch((error) => console.error('CKC error', error));
|
||
}
|
||
}
|
||
```
|