Rx-player + MPEG-Dash Widevine DRM + MS Smooth Streaming + ReactJS

Learn how to Rx-player through simple examples including MPEG-dash widevine DRMs.

Rx-player + MPEG-Dash Widevine DRM + MS Smooth Streaming  + ReactJS

What is Rx-player

From the official webpage:

The Rx-player is a library implementing a DASH and Microsoft Smooth Streaming video player directly on the browser, without plugins. It relies on HTML5 Media Source Extensions and Encrypted Media extensions and is written in TypeScript, a superset of JavaScript.

Create the React App

yarn create react-app my-app
cd my-app/
yarn add rx-player
yarn start

Please go to :
http://localhost:3000/

You should see something similar to this:
Screen Shot 2018-07-27 at 18.12.09.png

To try the following examples, simply replace the code defined in
my-app/src/App.js

MPEG-DASH example

Screen Shot 2018-07-27 at 18.10.51.png
import React, {Component} from 'react';
import RxPlayer from "rx-player";
RxPlayer.LogLevel = "DEBUG";

class App extends Component {

  constructor(props) {
    super(props)
    this.state = {}
  }

  componentDidMount() {
    this.initPlayer();
  }

  initPlayer() {
    const player = new RxPlayer({videoElement: document.getElementById("video")});
    player.loadVideo({
      url: "http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd",
      transport: "dash",
      autoPlay: false});
  }

  render() {
    return (
      <div className="App">
        <video id="video" controls></video>
      </div>
    );
  }
}

export default App;

MPEG-DASH + Widevine DRM

Screen Shot 2018-09-07 at 10.09.33.png

Widevine DRM system is compatible with Chrome, Firefox and Android.

Data are passed to the license server through a custom header.
In this example the custom header name is X-AxDRM-Message.
The custom header name depends on your DRM provider.

About Rx-player DRM behaviour

The encryption information can usually be at two places:

  • in the Manifest/MPD
  • in the initialization segments of the encrypted content

Rx-player trusts more what the segment contains than the manifest.

About the getLicence method

The getLicense method takes the "challenge" (message to generate the license) and has to perform the request to the license server. It should then return the license as an arraybuffer (wrapped in a promise for asynchronous functions).

Thanks to the Rx-player team for giving me those detailed information !

import React, {Component} from "react";
import RxPlayer from "rx-player";

RxPlayer.LogLevel = "DEBUG";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentDidMount() {
    console.log("did  mount");

    this.initPlayer();

  }
  initPlayer() {

    const player = new RxPlayer({videoElement: document.getElementById("video")});

    player.loadVideo({
      url: "//media.axprod.net/TestVectors/v6.1-MultiDRM/Manifest_1080p.mpd",
      transport: "dash",
      autoPlay: false,
      keySystems: [
        {
          type: "widevine",
          getLicense(message, messageType) {
            console.log("Message type: " + messageType);
            return new Promise((resolve, reject) => {
              return fetch("https://drm-widevine-licensing.axtest.net/AcquireLicense", {
                body: message,
                headers: {
                  "X-AxDRM-Message": 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiNmU1YTFkMjYtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflOPv9qHnu3ZWJNZ12jgkqTabmwXbDWk_47tLNE'
                },
                method: "POST"
              }).then((response) => {
                if (response.ok) {
                  response.arrayBuffer().then(function(buffer) {
                    resolve(buffer);
                  });
                } else {
                  reject(new Error('error'))
                }
              }, error => {
                reject(new Error(error.message))
              })
            });
          }
        }
      ]
    });
  }

  render() {
    return (
      <div className="App">
        <video id="video" controls></video>
      </div>
    );
  }
}

export default App;

Microsoft Smooth Streaming

Screen Shot 2018-07-27 at 18.31.03.png
import React, {Component} from 'react';
import RxPlayer from "rx-player";
RxPlayer.LogLevel = "DEBUG";

class App extends Component {

  constructor(props) {
    super(props)
    this.state = {}
  }

  componentDidMount() {
    this.initPlayer();
  }

  initPlayer() {
    const player = new RxPlayer({videoElement: document.getElementById("video")});
    player.loadVideo({
      url: "http://amssamples.streaming.mediaservices.windows.net/683f7e47-bd83-4427-b0a3-26a6c4547782/BigBuckBunny.ism/manifest",
      transport: "smooth",
      autoPlay: false});
  }

  render() {
    return (
      <div className="App">
        <video id="video" controls></video>
      </div>
    );
  }
}

export default App;

Information sources

RxPlayer homepage

https://github.com/canalplus/rx-player

Rx-player DRM discussion

https://github.com/canalplus/rx-player/issues/281

RxPlayer style

https://raw.githubusercontent.com/canalplus/rx-player/master/demo/full/styles/style.css

ReactJS

https://github.com/facebook/create-react-app

RxPlayer documentation

https://developers.canal-plus.com/rx-player/doc/pages/api/index.html
https://github.com/canalplus/rx-player/tree/master/doc/architecture

Media files & streams

https://github.com/Axinom/drm-quick-start
http://playready.azurewebsites.net/Home/AmsSamples


Share Tweet Send
0 Comments
Loading...