docs: update drm token generator links (#4263)
This commit is contained in:
parent
5b3add4e7a
commit
6080e96e82
@ -5,8 +5,8 @@
|
|||||||
documentation is available at [thewidlarzgroup.github.io/react-native-video/](https://thewidlarzgroup.github.io/react-native-video/)
|
documentation is available at [thewidlarzgroup.github.io/react-native-video/](https://thewidlarzgroup.github.io/react-native-video/)
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
We have examples that will show you basic usage of react-native-video [here](https://github.com/TheWidlarzGroup/react-native-video/tree/master/examples). <br />
|
You can find several examples demonstrating the usage of react-native-video [here](https://github.com/TheWidlarzGroup/react-native-video/tree/master/examples). <br />
|
||||||
Examples shows [basic](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/BasicExample.tsx) usage and [DRM example](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx) (with a free DRM stream).
|
These include a [basic](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/BasicExample.tsx) usage and [DRM example](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx) (with a [free DRM stream](https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=drm&utm_medium=code)).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -4,16 +4,14 @@ import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx';
|
|||||||
|
|
||||||
## DRM Example
|
## DRM Example
|
||||||
|
|
||||||
We have avaliable example for DRM usage in the [example app](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx).
|
We have available example for DRM usage in the [example app](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx).
|
||||||
To get token needed for DRM playback you can go to [our site]() and get it.
|
To get token needed for DRM playback you can go to [our site](https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=drm&utm_medium=docs) and get it.
|
||||||
|
|
||||||
## Provide DRM data (only tested with http/https assets)
|
## Provide DRM data (only tested with http/https assets)
|
||||||
|
|
||||||
You can provide some configuration to allow DRM playback.
|
You can provide some configuration to allow DRM playback.
|
||||||
This feature will disable the use of `TextureView` on Android.
|
This feature will disable the use of `TextureView` on Android.
|
||||||
|
|
||||||
```jsx
|
|
||||||
|
|
||||||
DRM object allows this members:
|
DRM object allows this members:
|
||||||
|
|
||||||
### `base64Certificate`
|
### `base64Certificate`
|
||||||
@ -49,8 +47,8 @@ your `contentId` + the provided certificate via `objc [loadingRequest streamingC
|
|||||||
contentIdentifier:contentIdData options:nil error:&spcError]; `
|
contentIdentifier:contentIdData options:nil error:&spcError]; `
|
||||||
|
|
||||||
Also, you will receive following parameter of getLicense:
|
Also, you will receive following parameter of getLicense:
|
||||||
* `contentId` contentId if passed to `drm` object or loadingRequest.request.url?.host
|
* `contentId` contentId if passed to `drm` object or loadingRequest.request.url?.host
|
||||||
* `loadedLicenseUrl` URL defined as `loadingRequest.request.URL.absoluteString`, this url starts with `skd://` or `clearkey://`
|
* `loadedLicenseUrl` URL defined as `loadingRequest.request.URL.absoluteString`, this url starts with `skd://` or `clearkey://`
|
||||||
* `licenseServer` prop if prop is passed to `drm` object.
|
* `licenseServer` prop if prop is passed to `drm` object.
|
||||||
* `spcString` the SPC used to validate playback with drm server
|
* `spcString` the SPC used to validate playback with drm server
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ const DRMExample = () => {
|
|||||||
|
|
||||||
// ------------- DMR Token -------------
|
// ------------- DMR Token -------------
|
||||||
// This token is used to authenticate the user and get the license
|
// This token is used to authenticate the user and get the license
|
||||||
// To run example please go to https://someweb.com (TODO: Insert here real website cc Kamil) and complete the form to receive the token
|
// To run example please go to https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=drm&utm_medium=code and complete the form to receive the token
|
||||||
// After you receive the token, please paste it here
|
// After you receive the token, please paste it here
|
||||||
const [token, setToken] = React.useState('<USER_TOKEN>');
|
const [token, setToken] = React.useState('<USER_TOKEN>');
|
||||||
|
|
||||||
|
@ -42,9 +42,7 @@ import {
|
|||||||
} from './constants';
|
} from './constants';
|
||||||
import {Overlay, toast, VideoLoader} from './components';
|
import {Overlay, toast, VideoLoader} from './components';
|
||||||
|
|
||||||
type Props = NonNullable<unknown>;
|
const BasicExample = () => {
|
||||||
|
|
||||||
const VideoPlayer: FC<Props> = ({}) => {
|
|
||||||
const [rate, setRate] = useState(1);
|
const [rate, setRate] = useState(1);
|
||||||
const [volume, setVolume] = useState(1);
|
const [volume, setVolume] = useState(1);
|
||||||
const [muted, setMuted] = useState(false);
|
const [muted, setMuted] = useState(false);
|
||||||
@ -243,6 +241,10 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
cacheSizeMB: useCache ? 200 : 0,
|
cacheSizeMB: useCache ? 200 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
videoRef.current?.setSource(currentSrc);
|
||||||
|
}, [currentSrc]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<StatusBar animated={true} backgroundColor="black" hidden={false} />
|
<StatusBar animated={true} backgroundColor="black" hidden={false} />
|
||||||
@ -252,8 +254,7 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
<Video
|
<Video
|
||||||
showNotificationControls={showNotificationControls}
|
showNotificationControls={showNotificationControls}
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
source={currentSrc as ReactVideoSource}
|
// source={currentSrc as ReactVideoSource}
|
||||||
adTagUrl={additional?.adTagUrl}
|
|
||||||
drm={additional?.drm}
|
drm={additional?.drm}
|
||||||
style={viewStyle}
|
style={viewStyle}
|
||||||
rate={rate}
|
rate={rate}
|
||||||
@ -341,4 +342,4 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default VideoPlayer;
|
export default BasicExample;
|
||||||
|
231
examples/expo/src/DRMExample.tsx
Normal file
231
examples/expo/src/DRMExample.tsx
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
StyleSheet,
|
||||||
|
Platform,
|
||||||
|
ScrollView,
|
||||||
|
TextInput,
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
ActivityIndicator,
|
||||||
|
} from 'react-native';
|
||||||
|
import Video, {DRMType, ReactVideoSourceProperties} from 'react-native-video';
|
||||||
|
|
||||||
|
type SourceType = ReactVideoSourceProperties | null;
|
||||||
|
|
||||||
|
const DRMExample = () => {
|
||||||
|
const [loading, setLoading] = React.useState(false);
|
||||||
|
|
||||||
|
const [source, setSource] = React.useState<SourceType>(null);
|
||||||
|
|
||||||
|
const [hls, setHls] = React.useState(
|
||||||
|
'https://d2e67eijd6imrw.cloudfront.net/559c7a7e-960d-4cd8-9dba-bc4e59890177/assets/47cfca69-91b5-4311-bf6c-b9b1f297ed9b/videokit-720p-dash-hls-drm/hls/index.m3u8',
|
||||||
|
);
|
||||||
|
const [fairplayLicense, setFairplayLicense] = React.useState(
|
||||||
|
'https://thewidlarzgroup.la.drm.cloud/acquire-license/fairplay?brandGuid=559c7a7e-960d-4cd8-9dba-bc4e59890177',
|
||||||
|
);
|
||||||
|
const [fairplayCertificate, setFairplayCertificate] = React.useState(
|
||||||
|
'https://thewidlarzgroup.la.drm.cloud/certificate/fairplay?brandGuid=559c7a7e-960d-4cd8-9dba-bc4e59890177',
|
||||||
|
);
|
||||||
|
const [dash, setDash] = React.useState(
|
||||||
|
'https://d2e67eijd6imrw.cloudfront.net/559c7a7e-960d-4cd8-9dba-bc4e59890177/assets/47cfca69-91b5-4311-bf6c-b9b1f297ed9b/videokit-720p-dash-hls-drm/dash/index.mpd',
|
||||||
|
);
|
||||||
|
const [widevineLicense, setWidevineLicense] = React.useState(
|
||||||
|
'https://thewidlarzgroup.la.drm.cloud/acquire-license/widevine?brandGuid=559c7a7e-960d-4cd8-9dba-bc4e59890177',
|
||||||
|
);
|
||||||
|
|
||||||
|
// ------------- DMR Token -------------
|
||||||
|
// This token is used to authenticate the user and get the license
|
||||||
|
// To run example please go to https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=drm&utm_medium=code and complete the form to receive the token
|
||||||
|
// After you receive the token, please paste it here
|
||||||
|
const [token, setToken] = React.useState('<USER_TOKEN>');
|
||||||
|
|
||||||
|
const handlePlayStopVideo = () => {
|
||||||
|
if (source !== null) {
|
||||||
|
setSource(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token === '<USER_TOKEN>') {
|
||||||
|
Alert.alert('Error', 'Please enter the token received from the website');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const newSource: ReactVideoSourceProperties = {};
|
||||||
|
|
||||||
|
if (Platform.OS === 'ios') {
|
||||||
|
if (fairplayLicense && fairplayCertificate) {
|
||||||
|
newSource.uri = hls;
|
||||||
|
newSource.drm = {
|
||||||
|
type: DRMType.FAIRPLAY,
|
||||||
|
licenseServer: fairplayLicense,
|
||||||
|
certificateUrl: fairplayCertificate,
|
||||||
|
getLicense: (spcString, contentId, licenseUrl, loadedLicenseUrl) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('spc', spcString);
|
||||||
|
|
||||||
|
const resultURL = loadedLicenseUrl.replace('skd://', 'https://');
|
||||||
|
|
||||||
|
return fetch(`${resultURL}&userToken=${token}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
Accept: 'application/json',
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((response) => {
|
||||||
|
return response.ckc;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
Alert.alert('Error', 'Please enter Fairplay License and Certificate');
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Platform.OS === 'android') {
|
||||||
|
if (widevineLicense) {
|
||||||
|
newSource.drm = {
|
||||||
|
type: DRMType.WIDEVINE,
|
||||||
|
licenseServer: widevineLicense,
|
||||||
|
};
|
||||||
|
newSource.uri = dash;
|
||||||
|
} else {
|
||||||
|
Alert.alert('Error', 'Please enter Widevine License');
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setSource(newSource);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>DRM is not supported on this platform</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
<Text style={styles.title}>DRM Protected Stream Player</Text>
|
||||||
|
|
||||||
|
{loading && <ActivityIndicator size="large" color="#0000ff" />}
|
||||||
|
{source && source.uri && (
|
||||||
|
<Video
|
||||||
|
key={source.uri}
|
||||||
|
onLoad={() => {
|
||||||
|
setLoading(false);
|
||||||
|
}}
|
||||||
|
onError={(e) => {
|
||||||
|
console.log('error', e);
|
||||||
|
Alert.alert('Error', e.error.localizedDescription);
|
||||||
|
setLoading(false);
|
||||||
|
}}
|
||||||
|
source={source}
|
||||||
|
resizeMode="contain"
|
||||||
|
style={styles.video}
|
||||||
|
controls
|
||||||
|
muted={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Platform.OS === 'ios' && (
|
||||||
|
<>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="HLS URL"
|
||||||
|
value={hls}
|
||||||
|
onChangeText={(text) => setHls(text)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Fairplay License URL"
|
||||||
|
value={fairplayLicense}
|
||||||
|
onChangeText={(text) => setFairplayLicense(text)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Fairplay Certificate URL"
|
||||||
|
value={fairplayCertificate}
|
||||||
|
onChangeText={(text) => setFairplayCertificate(text)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Platform.OS === 'android' && (
|
||||||
|
<>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="DASH URL"
|
||||||
|
value={dash}
|
||||||
|
onChangeText={(text) => setDash(text)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Widevine License URL"
|
||||||
|
value={widevineLicense}
|
||||||
|
onChangeText={(text) => setWidevineLicense(text)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Token"
|
||||||
|
value={token}
|
||||||
|
onChangeText={(text) => setToken(text)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
title={`${source !== null ? 'Stop' : 'Play'} Video`}
|
||||||
|
onPress={handlePlayStopVideo}
|
||||||
|
/>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DRMExample;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flexGrow: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: 'black',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 20,
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
width: '100%',
|
||||||
|
height: 200,
|
||||||
|
marginBottom: 80,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
height: 40,
|
||||||
|
borderColor: 'gray',
|
||||||
|
borderWidth: 1,
|
||||||
|
marginBottom: 10,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
width: '100%',
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
});
|
@ -107,6 +107,14 @@ export const srcAllPlatformList = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: '(mp4) big buck bunny With Ads',
|
||||||
|
ad: {
|
||||||
|
adTagUrl:
|
||||||
|
'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=',
|
||||||
|
},
|
||||||
|
uri: 'https://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const srcIosList: SampleVideoSource[] = [];
|
export const srcIosList: SampleVideoSource[] = [];
|
||||||
@ -133,12 +141,6 @@ export const srcAndroidList: SampleVideoSource[] = [
|
|||||||
uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
|
uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
|
||||||
type: 'mpd',
|
type: 'mpd',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: '(mp4) big buck bunny With Ads',
|
|
||||||
adTagUrl:
|
|
||||||
'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=',
|
|
||||||
uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: 'WV: Secure SD & HD (cbcs,MP4,H264)',
|
description: 'WV: Secure SD & HD (cbcs,MP4,H264)',
|
||||||
uri: 'https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd',
|
uri: 'https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user