Rx-Player
1. Introduction
This section will provide information on integrating SigmaMultiDRM system into Rx-Player:
::: Information
- Widevine:
- Playready:
In which, MERCHANT_ID and APP_ID will be obtained from Dashboard.
2. Require
::: Prerequisite
- Html 5 Browsers:
Html 5 browsers | Widevine | PlayReady | FairPlay | License encryption support |
---|---|---|---|---|
Chrome (Window, MacOS, Android, ChromeOS, Linux) | Yes | No | No | Yes |
Firefox (Window, MacOS, Linux) | Yes | No | No | Yes |
Microsoft Edge (Window, MacOS, Android) | Yes | Yes | No | No |
Safari (Safari 8+ on MacOS, Safari on iOS 11.2+) | No | No | Yes | No |
iOS Browser (Chrome, Cốc Cốc, Microsoft Edge, Firefox, Opera) | No | No | Yes | No |
Opera (Window, MacOS) | Yes | No | No | Yes |
Internet Explorer (Window 8.1+) | No | Yes | Yes | No |
- Smart TVs:
Smart TVs | Widevine | PlayReady | FairPlay | License encryption support |
---|---|---|---|---|
SamSung Tizen (2016-2017, 2018+ Models) | Yes | Yes | No | No |
SamSung Tizen&Orsay (2010-2015 Models) | No | Yes | No | No |
LG (WebOS 3.0+) | Yes | Yes | No | No |
LG (WebOS 1.2 & Netcast) | No | Yes | No | No |
Smart TV Alliance (LG, Philips, Toshiba, Panasonic) | Yes | Yes | No | No |
Android TV | Yes | Yes | No | No |
3. Integrate license into Rx-Player
3.1. Add script tag to load Sigma Packer SDK
To use the license encryption feature, you need to install the Sigma Packer SDK into your application
Installing the SDK
Source: sigma_packer.js
Add script:
html<script src="sigma_packer.js"></script>
Note: The implementation will be presented in the following sections
3.2 Implementation utils feature
javascript
// With HTML5 SmartTV, you don't need call function initApp
function initApp() {
if (window)
window.sigmaPacker = new SigmaPacker();
window.sigmaPacker.onload = () => {
console.log('DataPacker: Loaded');
};
window.sigmaPacker.init();
}
function initPlayer() {
const videoElement = document.getElementById("video");
player = new RxPlayer({ videoElement });
player.addEventListener("error", (err) => {
console.log("the content stopped with the following error", err);
});
player.addEventListener("playerStateChange", (state) => {
if (state === "LOADED") {
console.log("The content is loaded");
// toggle between play and pause when the user clicks on the video
videoElement.onclick = function () {
if (player.getPlayerState() === "PLAYING") {
player.pause();
} else {
player.play();
}
};
}
});
}
function base64ToArrayBuffer(base64) {
var binaryString = atob(base64);
var bytes = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
function formatPlayreadyChallenge(challenge) {
let u8Challenge;
if (!(challenge instanceof Uint8Array)) {
if (challenge instanceof ArrayBuffer) {
u8Challenge = new Uint8Array(challenge);
} else {
u8Challenge = new Uint8Array(challenge.buffer);
}
} else {
u8Challenge = challenge;
}
const str = leUtf16ToStr(u8Challenge);
const match = /<Challenge encoding="base64encoded">(.*)<\/Challenge>/.exec(str);
const xml = match ?
atob(match[1]) : utf8ToStr(u8Challenge);
return xml;
}
function leUtf16ToStr(bytes) {
let str = "";
for (let i = 0; i < bytes.length; i += 2) {
str += String.fromCharCode((bytes[i + 1] << 8) + bytes[i]);
}
return str;
}
3.3 Implementation get license Api
javascript
const licenseWidevineServer = LICENSE_WIDEVINE_URL;
const licensePlayReadyServer = LICENSE_PLAYREADY_URL;
function getLicense(rawChallenge, isPlayready = false) {
const challenge = isPlayready ? formatPlayreadyChallenge(rawChallenge) : rawChallenge;
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', isPlayready ? licensePlayReadyServer : widevineLicenseURI, true);
// With HTML5 SmartTV, you don't need get information from Sigma Packer
const packInfo = window.sigmaPacker.getDataPacker(challenge) || {};
xhr.setRequestHeader(
'custom-data',
btoa(
JSON.stringify({
userId: 'USER_ID',
sessionId: 'SESSION_ID',
merchantId: 'MERCHANT_ID',
appId: 'APP_ID',
// With HTML5 SmartTV, you don't need add reqId and deviceInfo to custom-data header
reqId: packInfo.requestId,
deviceInfo: packInfo.deviceInfo,
})
)
);
xhr.onerror = (err) => {
reject(err);
};
xhr.onload = (evt) => {
if (xhr.status >= 200 && xhr.status < 300) {
const response = evt.target.response;
const { license } = response;
const licenseBuffer = base64ToArrayBuffer(license);
// With HTML5 SmartTV, you don't need update clientInfo
let clientInfo = response.clientInfo;
if (clientInfo) {
window.sigmaPacker.update(JSON.stringify(clientInfo));
} else {
if (xhr.readyState === xhr.HEADERS_RECEIVED) {
clientInfo = xhr.getResponseHeader('client-info');
if (clientInfo) {
window.sigmaPacker.update(atob(clientInfo));
}
}
}
resolve(licenseBuffer);
} else {
const error = new Error(
"getLicense's request finished with a " + `${xhr.status} HTTP error`
);
reject(error);
}
};
if (isPlayready) {
xhr.setRequestHeader("content-type", "text/xml; charset=utf-8");
}
xhr.responseType = 'json';
xhr.send(challenge);
});
}
In where:
Props | Type | Description |
---|---|---|
licenseWidevineServer | String | See heading 1. Introduction |
licensePlayReadyServer | String | See heading 1. Introduction |
CERTIFICATE_URI | String | See heading 1. Introduction |
MERCHANT_ID | String | Id of merchant's user |
APP_ID | String | Id of application |
USER_ID | String | UserId of merchant's client |
SESSION_ID | String | SessionId of merchant's client |
3.4 Implementation load video
javascript
function loadVideo(manifestUri) {
player.loadVideo({
url: manifestUri,
transport: 'dash',
autoPlay: true,
keySystems: [
{
type: 'widevine',
getLicense: function(challenge) {
return getLicense(challenge)
},
getLicenseConfig: {
retry: 3,
timeout: -1,
},
},
{
type: 'playready',
getLicense: function(challenge) {
return getLicense(challenge, true)
},
getLicenseConfig: {
retry: 3,
timeout: -1,
},
},
],
});
}
3.4.2. Call all function together
javascript
// Note: Always call initApp before initPlayer();
initApp();
initPlayer();
loadVideo(manifestUri)
In where:
Props | Type | Description |
---|---|---|
manifestUri | String | The URL of the content you want to see |