Skip to content
On this page

Hướng dẫn sử dụng Shaka Player ​

1. Giới thiệu ​

Phần này sẽ cung cấp thông tin để tích hợp hệ thống SigmaMultiDRM vào trình phát shaka player:

::: Thông tin

Trong đó, MERCHANT_ID và APP_ID có thể được lấy từ hệ thống Dashboard như hình dưới đây.

get_customer_info :::

2. Yêu cầu ​

::: Thông tin yêu cầu

  • Trình duyệt hỗ trợ Html5:
Trình duyệtWidevinePlayReadyFairPlayHỗ trợ 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ợ 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 Sigma MultiDRM vào Shaka Player ​

3.1. Sử dụng tính năng mã hóa license sử dụng Sigma Packer SDK ​

Để sử dụng tính năng mã hóa giấy phép, bạn cần cài đặt Sigma Packer SDK vào trong ứng dụng

Cài đặt SDK

  • Địa chỉ: sigma_packer.js

  • Thêm mã nguồn:

    html
    <script src="sigma_packer.js"></script>
    <script src="shaka-player.compiled.js"></script>

Chú ý: Việc cài đặt theo từng bước dưới đây

3.2 Init application ​

  • Mặc định
javascript
var player;
document.addEventListener('DOMContentLoaded', function () {
  shaka.polyfill.installAll();
  var video = document.getElementById('VIDEO_ID'); // media element
  player = new this.shaka.Player(video);
});
  • Tính năng mã hóa license: Bạn cần chạy shaka polyfill sau khi SigmaPacker được khởi tạo:
javascript
var player;
document.addEventListener('DOMContentLoaded', function () {
  var video = document.getElementById('VIDEO_ID'); // media element
  player = new this.shaka.Player(video);

  window.sigmaPacker = new SigmaPacker();
  window.sigmaPacker.onload = () => {
    console.log('SigmaPacker loaded');
    shaka.polyfill.installAll();
  };
  window.sigmaPacker.init();
});

Note: Nếu bạn đang sử dụng ReactJS, hãy đặt đoạn mã này vào tệp src/App.js ngay sau import các tiện ích được sử dụng để khởi tạo SigmaPacker.

javascript
// src/App.js
import ... from "...";
import ... from "...";

window.sigmaPacker = new SigmaPacker();
window.sigmaPacker.onload = () => {
  console.log('SigmaPacker loaded');
  shaka.polyfill.installAll();
};
window.sigmaPacker.init();
// do something

3.3 Cấu hình trình phát video sử dụng địa chỉ máy chủ của hệ thống Sigma MultiDRM ​

javascript
const manifestUri = MANIFEST_URI;
const licenseWidevineServer = LICENSE_WIDEVINE_URL;
const licensePlayReadyServer = LICENSE_PLAYREADY_URL;
const licenseFairPlayServer = LICENSE_FAIRPLAY_URL;

player.configure({
  drm: {
    servers: {
      'com.widevine.alpha': licenseWidevineServer,
      'com.microsoft.playready': licensePlayReadyServer,
      'com.apple.fps.1_0': licenseFairPlayServer,
    },
  },
});
// Try to load a manifest.
try {
  await player.load(manifestUri);
  // The video should now be playing!
} catch (e) {
  console.error(e);
}
TrườngKiểuMô tả
licenseWidevineServerStringXem mục 1
licensePlayReadyServerStringXem mục 1
licenseFairPlayServerStringXem mục 1
manifestUriStringURL của nội dung muốn xem

3.4 Thông tin cấu hình header của yêu cầu ​

Thông tin cấu hình:

PropsTypeDescription
CERTIFICATE_URIStringXem mục 1
MERCHANT_IDStringĐịnh danh khách hàng
APP_IDStringĐịnh danh ứng dụng
USER_IDStringĐịnh danh người dùng trên hệ thống của khách hàng
SESSION_IDStringMã xác thực của người dùng được cấp bởi hệ thống của khách hàng

3.4.1 Cấu hình header cho FairPlay ​

javascript
var licenseURL; // Biến lưu thông tin địa chỉ request license
// Đầu tiên cần cấu hình certificate
const serverCertificateURI = CERTIFICATE_URI; // xem mục 1
const response = await fetch(serverCertificateURI);
if (!response.ok) {
  console.error('Could not get certificate!');
  return;
}
const certificate = await response.arrayBuffer();
player.configure({
  drm: {
    advanced: {
      'com.apple.fps.1_0': {
        serverCertificate: new Uint8Array(certificate),
      },
    },
  },
});
// Chỉnh sửa thông tin nội dung (assetId) và lưu thông tin licenseURL
player.configure('drm.initDataTransform', (initData, type, drmInfo) => {
  if (type != 'skd') return initData;
  const skdURL = shaka.util.StringUtils.fromBytesAutoDetect(initData);
  const contentId = new URL(skdURL).searchParams.get('assetId');
  const cert = player.drmInfo().serverCertificate;
  licenseURL = skdURL.replace('skd://', 'https://');
  return shaka.util.FairPlayUtils.initDataTransform(initData, contentId, cert);
});
// Tùy chỉnh request lấy license
player.getNetworkingEngine().registerRequestFilter(function (type, request) {
  if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
    request.uris = [licenseURL];
    request.method = 'POST';
    request.headers['Content-Type'] = 'application/json';
    request.headers['custom-data'] = btoa(
      JSON.stringify({
        userId: 'USER_ID',
        sessionId: 'SESSION_ID',
        merchantId: 'MERCHANT_ID',
        appId: 'APP_ID',
      })
    );
    const originalPayload = new Uint8Array(request.body);
    const base64Payload =
      shaka.util.Uint8ArrayUtils.toStandardBase64(originalPayload);
    request.body = JSON.stringify({
      spc: base64Payload,
      assetId: new URL(licenseURL).searchParams.get('assetId'),
    });
  }
});

3.4.2. Cấu hình header cho Widevine or PlayReady ​

javascript
player.getNetworkingEngine().registerRequestFilter(function (type, request) {
  // Only add headers to license requests:
  if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
    // This is the specific header name and value the server wants:

    request.headers['Content-Type'] = 'application/octet-stream';
    request.headers['custom-data'] = btoa(
      JSON.stringify({
        userId: 'USER_ID',
        sessionId: 'SESSION_ID',
        merchantId: 'MERCHANT_ID',
        appId: 'APP_ID',
      })
    );
  }
});

Nếu bạn sử dụng tính năng mã hóa license, bạn cần thêm một vài trường vào trong header như sau:

javascript
player.getNetworkingEngine().registerRequestFilter(function (type, request) {
  const StringUtils = shaka.util.StringUtils;
  const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
  if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
    // This is the specific header name and value the server wants:
    const packInfo = window.sigmaPacker.getDataPacker(request.body) || {};
    request.headers['Content-Type'] = 'application/octet-stream';
    request.headers['custom-data'] = btoa(
      JSON.stringify({
        userId: 'USER_ID',
        sessionId: 'SESSION_ID',
        merchantId: 'MERCHANT_ID',
        appId: 'APP_ID',
        reqId: packInfo.requestId,
        deviceInfo: packInfo.deviceInfo,
      })
    );
  }
});
PropsTypeDescription
MERCHANT_IDStringĐịnh danh khách hàng
APP_IDStringĐịnh danh ứng dụng
USER_IDStringĐịnh danh người dùng trên hệ thống của khách hàng
SESSION_IDStringMã xác thực của người dùng được cấp bởi hệ thống của khách hàng

3.5 Cấu hinh thông tin trả về ​

Cấu hình cho Widevine, PlayReady và FairPlayer là giống nhau và như sau:

javascript
player.getNetworkingEngine().registerResponseFilter(function (type, response) {
  var StringUtils = shaka.util.StringUtils;
  var Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

  // Only manipulate license responses:
  if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
    // This is the wrapped license, which is a JSON string.
    try {
      var wrappedString = StringUtils.fromUTF8(response.data);
      // Parse the JSON string into an object.
      var wrapped = JSON.parse(wrappedString);

      // This is a base64-encoded version of the raw license.
      var rawLicenseBase64 = wrapped.license;
      // Decode that base64 string into a Uint8Array and replace the response
      // data.  The raw license will be fed to the Widevine CDM.
      response.data = Uint8ArrayUtils.fromBase64(rawLicenseBase64);

      // Read additional fields from the server.
      // The server we are using in this tutorial does not send anything useful.
      // In practice, you could send any license metadata the client might need.
      // Here we log what the server sent to the JavaScript console for
      // inspection.
      console.log(wrapped);
    } catch (err) {}
  }
});

Nếu bạn sử dụng tính năng mã hóa license, bạn cần làm thêm như sau:

javascript
player.getNetworkingEngine().registerResponseFilter(function (type, response) {
  // Alias some utilities provided by the library.
  const StringUtils = shaka.util.StringUtils;
  const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

  // Only manipulate license responses:
  if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
    // This is the wrapped license, which is a JSON string.
    try {
      const wrappedString = StringUtils.fromUTF8(response.data);
      // Parse the JSON string into an object.
      const wrapped = JSON.parse(wrappedString);

      if (response.headers['client-info']) {
        console.log(response.headers['client-info']);
        window.sigmaPacker.update(atob(response.headers['client-info']));
      } else if (wrapped.clientInfo) {
        console.log(wrapped.clientInfo);
        window.sigmaPacker.update(JSON.stringify(wrapped.clientInfo));
      }

      // This is a base64-encoded version of the raw license.
      const rawLicenseBase64 = wrapped.license;
      // Decode that base64 string into a Uint8Array and replace the response
      // data.  The raw license will be fed to the Widevine CDM.
      response.data = Uint8ArrayUtils.fromBase64(rawLicenseBase64);
      // Read additional fields from the server.
      // The server we are using in this tutorial does not send anything useful.
      // In practice, you could send any license metadata the client might need.
      // Here we log what the server sent to the JavaScript console for
      // inspection.
      console.log(wrapped);
    } catch (err) {}
  }
});

4. Mẫu ​

Mã nguồn mẫu