Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ideo into dev-android-cache
  • Loading branch information
lovegaoshi committed Mar 8, 2024
2 parents 88b4bff + 0f31271 commit 55c8ab1
Show file tree
Hide file tree
Showing 51 changed files with 3,504 additions and 2,727 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
Expand Down Expand Up @@ -129,18 +128,19 @@ public void setDRM(final ReactExoplayerView videoView, @Nullable ReadableMap drm
if (drm != null && drm.hasKey(PROP_DRM_TYPE)) {
String drmType = ReactBridgeUtils.safeGetString(drm, PROP_DRM_TYPE);
String drmLicenseServer = ReactBridgeUtils.safeGetString(drm, PROP_DRM_LICENSESERVER);
ReadableMap drmHeaders = ReactBridgeUtils.safeGetMap(drm, PROP_DRM_HEADERS);
ReadableArray drmHeadersArray = ReactBridgeUtils.safeGetArray(drm, PROP_DRM_HEADERS);
if (drmType != null && drmLicenseServer != null && Util.getDrmUuid(drmType) != null) {
UUID drmUUID = Util.getDrmUuid(drmType);
videoView.setDrmType(drmUUID);
videoView.setDrmLicenseUrl(drmLicenseServer);
if (drmHeaders != null) {
if (drmHeadersArray != null) {
ArrayList<String> drmKeyRequestPropertiesList = new ArrayList<>();
ReadableMapKeySetIterator itr = drmHeaders.keySetIterator();
while (itr.hasNextKey()) {
String key = itr.nextKey();
for (int i = 0; i < drmHeadersArray.size(); i++) {
ReadableMap current = drmHeadersArray.getMap(i);
String key = current.hasKey("key") ? current.getString("key") : null;
String value = current.hasKey("value") ? current.getString("value") : null;
drmKeyRequestPropertiesList.add(key);
drmKeyRequestPropertiesList.add(drmHeaders.getString(key));
drmKeyRequestPropertiesList.add(value);
}
videoView.setDrmLicenseHeader(drmKeyRequestPropertiesList.toArray(new String[0]));
}
Expand All @@ -158,7 +158,20 @@ public void setSrc(final ReactExoplayerView videoView, @Nullable ReadableMap src
int cropEndMs = ReactBridgeUtils.safeGetInt(src, PROP_SRC_CROP_END, -1);
String extension = ReactBridgeUtils.safeGetString(src, PROP_SRC_TYPE, null);

Map<String, String> headers = src.hasKey(PROP_SRC_HEADERS) ? ReactBridgeUtils.toStringMap(src.getMap(PROP_SRC_HEADERS)) : new HashMap<>();
Map<String, String> headers = new HashMap<>();
ReadableArray propSrcHeadersArray = ReactBridgeUtils.safeGetArray(src, PROP_SRC_HEADERS);
if (propSrcHeadersArray != null) {
if (propSrcHeadersArray.size() > 0) {
for (int i = 0; i < propSrcHeadersArray.size(); i++) {
ReadableMap current = propSrcHeadersArray.getMap(i);
String key = current.hasKey("key") ? current.getString("key") : null;
String value = current.hasKey("value") ? current.getString("value") : null;
if (key != null && value != null) {
headers.put(key, value);
}
}
}
}

if (TextUtils.isEmpty(uriString)) {
videoView.clearSrc();
Expand Down
Binary file modified docs/bun.lockb
Binary file not shown.
8 changes: 8 additions & 0 deletions docs/components/PlatformsList/PlatformsList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.paragraphStyle {
margin-top: 10;
}

.spanStyle {
font-family: 'Orbitron';
font-weight: 800;
}
28 changes: 28 additions & 0 deletions docs/components/PlatformsList/PlatformsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import styles from './PlatformsList.module.css';

type Platform =
| 'Android'
| 'iOS'
| 'visionOS'
| 'tvOS'
| 'Windows UWP'
| 'Web'
| 'All';

interface Platforms {
types: Platform[];
}

function PlatformsList({types}: Platforms) {
return (
<p className={styles.paragraphStyle}>
{types.length === 1 && !types.includes('All')
? 'Platform:'
: 'Platforms:'}
<span className={styles.spanStyle}>{' ' + types.join(' | ')}</span>
</p>
);
}

export default PlatformsList;
3 changes: 2 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"typescript": "^5.4.2"
},
"devDependencies": {
"bun-types": "latest"
Expand Down
93 changes: 62 additions & 31 deletions docs/pages/component/drm.md → docs/pages/component/drm.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx';

# DRM

> **Note:** DRM is not supported on visionOS yet.
Expand All @@ -9,37 +11,40 @@ This feature will disable the use of `TextureView` on Android.

DRM object allows this members:

| Property | Type | Default | Platform | Description |
| --- | --- | --- | --- | --- |
| [`type`](#type) | DRMType | undefined | iOS/Android | Specifies which type of DRM you are going to use, DRMType is an enum exposed on the JS module ('fairplay', 'playready', ...) |
| [`licenseServer`](#licenseserver) | string | undefined | iOS/Android | Specifies the license server URL |
| [`headers`](#headers) | Object | undefined | iOS/Android | Specifies the headers send to the license server URL on license acquisition |
| [`contentId`](#contentid) | string | undefined | iOS | Specify the content id of the stream, otherwise it will take the host value from `loadingRequest.request.URL.host` (f.e: `skd://testAsset` -> will take `testAsset`) |
| [`certificateUrl`](#certificateurl) | string | undefined | iOS | Specifies the url to obtain your ios certificate for fairplay, Url to the .cer file |
| [`base64Certificate`](#base64certificate) | bool | false | iOS | Specifies whether or not the certificate returned by the `certificateUrl` is on base64 |
| [`getLicense`](#getlicense)| function | undefined | iOS | Rather than setting the `licenseServer` url to get the license, you can manually get the license on the JS part, and send the result to the native part to configure FairplayDRM for the stream |

### `base64Certificate`

Whether or not the certificate url returns it on base64.
<PlatformsList types={['iOS']} />

Type: bool\
Default: false

Platforms: iOS
Whether or not the certificate url returns it on base64.

### `certificateUrl`

URL to fetch a valid certificate for FairPlay.
<PlatformsList types={['iOS']} />

Platforms: iOS
Type: string\
Default: undefined

URL to fetch a valid certificate for FairPlay.

### `getLicense`

`licenseServer` and `headers` will be ignored. You will obtain as argument the `SPC` (as ASCII string, you will probably need to convert it to base 64) obtained from your `contentId` + the provided certificate via
```objc
[loadingRequest streamingContentKeyRequestDataForApp:certificateData contentIdentifier:contentIdData options:nil error:&spcError];
```
<PlatformsList types={['iOS']} />

Type: function\
Default: undefined

Rather than setting the `licenseServer` url to get the license, you can manually get the license on the JS part, and send the result to the native part to configure FairplayDRM for the stream

`licenseServer` and `headers` will be ignored. You will obtain as argument the `SPC`
(as ASCII string, you will probably need to convert it to base 64) obtained from
your `contentId` + the provided certificate via `objc [loadingRequest streamingContentKeyRequestDataForApp:certificateData
contentIdentifier:contentIdData options:nil error:&spcError]; `

Also, you will receive the `contentId` and a `licenseUrl` URL defined as `loadingRequest.request.URL.absoluteString ` or as the `licenseServer` prop if it's passed.

You should return on this method a `CKC` in Base64, either by just returning it or returning a `Promise` that resolves with the `CKC`.

With this prop you can override the license acquisition flow, as an example:
Expand All @@ -50,24 +55,31 @@ getLicense: (spcString, contentId, licenseUrl) => {
const formData = new FormData();
formData.append('spc', base64spc);
return fetch(`https://license.pallycon.com/ri/licenseManager.do`, {
method: 'POST',
headers: {
'pallycon-customdata-v2': 'd2VpcmRiYXNlNjRzdHJpbmcgOlAgRGFuaWVsIE1hcmnxbyB3YXMgaGVyZQ==',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData
}).then(response => response.text()).then((response) => {
method: 'POST',
headers: {
'pallycon-customdata-v2':
'd2VpcmRiYXNlNjRzdHJpbmcgOlAgRGFuaWVsIE1hcmnxbyB3YXMgaGVyZQ==',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData,
})
.then((response) => response.text())
.then((response) => {
return response;
}).catch((error) => {
})
.catch((error) => {
console.error('Error', error);
});
}
});
};
```

Platforms: iOS

### `headers`

<PlatformsList types={['Android', 'iOS']} />

Type: Object\
Default: undefined

You can customize headers send to the licenseServer.

Example:
Expand All @@ -87,14 +99,33 @@ drm={{

### `licenseServer`

<PlatformsList types={['Android', 'iOS']} />

Type: string\
Default: false

The URL pointing to the licenseServer that will provide the authorization to play the protected stream.

### `type`

<PlatformsList types={['Android', 'iOS']} />

Type: DRMType\
Default: undefined

You can specify the DRM type, either by string or using the exported DRMType enum.
Valid values are, for Android: DRMType.WIDEVINE / DRMType.PLAYREADY / DRMType.CLEARKEY.
for iOS: DRMType.FAIRPLAY

### `contentId`

<PlatformsList types={['iOS']} />

Type: string\
Default: undefined

Specify the content id of the stream, otherwise it will take the host value from `loadingRequest.request.URL.host` (f.e: `skd://testAsset` -> will take `testAsset`)

## Common Usage Scenarios

### Send cookies to license server
Expand Down
Loading

0 comments on commit 55c8ab1

Please sign in to comment.