Skip to content
On this page

Rx-Player

1. Giới thiệu

Phần này sẽ giới thiệu cách tích hợp hệ thống SigmaMultiDRM vào Rx-Player:

::: Thông tin

Trong đó, MERCHANT_ID and APP_ID sẽ được lấy từ hệ thống Dashboard.

get_customer_info :::

2. Yêu cầu

::: Điều kiện tiên quyết

  • Html 5 Browsers:
Html 5 browsersWidevinePlayReadyFairPlayHỗ trợ tính năng mã hóa license
Chrome (Window, MacOS, Android, ChromeOS, Linux)YesNoNoYes
Firefox (Window, MacOS, Linux)YesNoNoYes
Microsoft Edge (Window, MacOS, Android)YesYesNoNo
Safari (Safari 8+ on MacOS, Safari on iOS 11.2+)NoNoYesNo
iOS Browser (Chrome, Cốc Cốc, Microsoft Edge, Firefox, Opera)NoNoYesNo
Opera (Window, MacOS)YesNoNoYes
Internet Explorer (Window 8.1+)NoYesYesNo
  • Smart TVs:
Smart TVsWidevinePlayReadyFairPlayHỗ trợ tính năng mã hóa license
SamSung Tizen (2016-2017, 2018+ Models)YesYesNoNo
SamSung Tizen&Orsay (2010-2015 Models)NoYesNoNo
LG (WebOS 3.0+)YesYesNoNo
LG (WebOS 1.2 & Netcast)NoYesNoNo
Smart TV Alliance (LG, Philips, Toshiba, Panasonic)YesYesNoNo
Android TVYesYesNoNo

:::

3. Tích hợp vào Rx-Player

3.1. Thêm thẻ script để tải SigmaPacker

Để sử dụng tính năng mã hóa license, bạn cần phải tải Sigma Packer SDK vào trong ứng dụng của bạn

Cài đặt 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 Cài đặt các tính năng hỗ trợ

javascript
function initApp() {
  if (windwo)
  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 Cài đặt phần giao tiếp với hệ thống của Sigma Multi DRM

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);
    const packInfo = window.sigmaPacker.getDataPacker(challenge) || {};

    // Với nền tàng HTML5 SmartTV, thì bạn không cần cấu hình custom-data trong header
    xhr.setRequestHeader(
      'custom-data',
      btoa(
        JSON.stringify({
          userId: 'USER_ID',
          sessionId: 'SESSION_ID',
          merchantId: 'MERCHANT_ID',
          appId: 'APP_ID',
          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);

        // Với nền tàng HTML5 SmartTV, thì bạn không cần cập nhật thông tin của 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);
  });
}

Trong đó:

TrườngKiểuMô tả
licenseWidevineServerStringXem mục 1. Giới thiệu
licensePlayReadyServerStringXem mục 1. Giới thiệu
CERTIFICATE_URIStringXem mục 1. Giới thiệu
MERCHANT_IDStringĐịnh danh của khách hàng
APP_IDStringĐịnh danh của ứng dụng
USER_IDStringĐịnh danh người dùng của khách hàng
SESSION_IDStringMã phiên sử dụng của người dùng của khách hàng

3.4 Cài đặt phần tải nội dung

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. Kết hợp các chức năng với nhau

javascript
// Note: Luôn gọi hàm initApp trước hàm initPlayer;
initApp();
initPlayer();
loadVideo(manifestUri)

Trong đó:

TrườngKiểuMô tả
manifestUriStringĐịa chỉ của nội dung

4. Demo

Sample Demo