JavaScript
HTML5
streaming
DRM
reactjs

Rx-player + MPEG-Dash Widevine DRM + MS Smooth Streaming + ReactJSの使用法


はじめに

こんにちは streampack チームのメディです。

https://cloudpack.jp/service/option/streampack.html

In my opinion Rx-Player is a really interesting player and I would like to show you common use cases.

Rx-Player は興味深いプレイヤーなので、一般的な使用法を説明します。


Copyrights of videos

Big Buck Bunny

© copyright 2008, Blender Foundation | www.bigbuckbunny.org

Tears of Steel

© copyright Blender Foundation | https://mango.blender.org/


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.


公式ウェブページから:


Rxプレーヤーは、DASHおよびMicrosoft Smooth Streamingビデオプレーヤーをプラグインなしでブラウザに直接実装するライブラリです。 HTML5 Media Source ExtensionsとEncrypted Media拡張機能に依存しています。 RxプレーヤーはTypeScriptで書かれています。



Create the React App ・ React Appを作成してください

yarn create react-app my-app

cd my-app/

yarn add rx-player

yarn start

Please go to :

次のURLにアクセスしてください:

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

次の例を試すには、my-app/src/App.js


MPEG-DASH example

Screen Shot 2018-07-27 at 18.10.51.png


App.js

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.

Widevine DRMシステムは、Chrome、Firefox、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.

データは、カスタムヘッダーを介してライセンスサーバーに渡されます。

この例では、カスタムヘッダー名はX-AxDRM-Messageです。

カスタムヘッダ名はDRMプロバイダによって異なります。


About Rx-player DRM behaviour ・ Rx-playerのDRM動作について

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.

暗号化情報は通常2つの場所にあります。


  • MPDマニフェスト

  • 暗号化されたコンテンツの初期化セグメント

Rx-playerは、セグメントに含まれるものがマニフェストよりも信頼しています。


About the getLicence method ・getLicenceメソッドについて

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).

getLicense メソッドはパラメータとして「チャレンジ」(ライセンスを生成するメッセージ)を受け取り、ライセンスサーバーへの要求を実行する必要があります。

ライセンスを arraybuffer(非同期関数の promise で囲んだもの)として返します。

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

詳細な情報を提供してくれたRx-playerチームに感謝します!


App.js

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


App.js

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