Azure Media Services の移行・お引越し・Migration: MediaKind 編 (2) MKPlayer 設定

さて。前回から間が空きました。

https://qiita.com/dahatake/items/9a7255a3626a5441d3ad

前回は Azure Media Service の Dynamic Packaging 用にエンコードされたファイル。そのファイルを MK/IO から参照できるようにした状態で。

続きをやっていきましょう😎
MKPlayer の組み込みを実施します。具体的には HTML としての埋め込みですね。

# 作戦

MKPlayer は、npm のパッケージとして提供されています。そのため、ローカルの Player 環境で web アプリへ組み込みます。Webアプリは、**Azure Static Web App** で動かします。**ローカルだと動かない**です😅

ドキュメントはこちらですね。

https://docs.io.mediakind.com/docs/player-sdk

https://www.npmjs.com/package/@mediakind/mkplayer


Azure Static Web Apps のドキュメントはこちら。

https://learn.microsoft.com/ja-jp/azure/static-web-apps/overview

# 必要なもの

- Azure の Subscription
    - Web アプリのホスティングが必要です
- MK/IO の契約
    - これは前回の手順で
- GitHub のアカウント
    - Azure Static Web Apps にアプリをデプロイするために使います


# 手順

前回の続きとなります。

事前にMK/IO の Streaming Endpoint を起動させるのをお忘れなきように。

## 1. MK/IO ポータルでの動作確認

[Assets] の画面から、当該ファイルの動作確認を行います。
はい、再生できていますね😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e5fbb279-7cb4-e532-6a1f-dc7770204bca.png)

で。
**DASH**と**HLS**の2つのURLが取得できます。これは、**Azure Media Service と同じ書式**ですね。
で、**双方 CMAF のコンテナ**である点にも留意ください。ファイルとしては同じですので **CDN のキャッシュ**も有効活用できます。素晴らしい。

これが、実際のHLS の URLです。

| https://ep-dahatakeorigin01-dahatakemediakindio.japaneast.streaming.mediakind.com/fa2b4e01-685f-4cd6-aef0-4733d7a513a5/Common_60.ism/manifest(format=m3u8-cmaf)

今、皆さんがアクセスしても動きませんよ😊 Streaming Endpoint をまめに停止させてますから。


次に、[MKPlayer] へ移動します。

[Protocol] は **HLS**を選択して。
[Source URL] に、先ほどの HLS のURLを貼り付けます


はい。動いていますね。仕組みがわかってきましたね😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/28171314-8b51-be32-2991-782d1c29812a.png)


注意したいのは、画面上部にある MKPlayer の**ライセンスコード**です。
MKPlayer を実際に使う際には、このライセンスコードが必要です。セキュアに扱う必要がありますね。APIから取得するなどして。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/9cd00146-1f0c-66f3-5a1b-d367be13368a.png)


## 2. Player の作成

MKPlayer は JavaScript のアプリケーションです。HTMLに組み込めば動きます。

## 2.1. 環境作成

準備していきましょう。

### 2.1.1. 作業用フォルダーの作成

作業用フォルダーを作成します。そのままPlayerアプリのフォルダー扱いですね。

ここでは、**C:\Work\mkplayer** としています。

### 2.1.2. Visual Studio Code の整備

**Visual Studio Code** を起動します。
こちらのドキュメントが何かあった際のお助けに。

https://learn.microsoft.com/ja-jp/azure/developer/javascript/how-to/with-visual-studio-code/install-run-debug-nodejs

## 2.2. MKPlayer のインストール

それでは、MKPlayerのインストールをします。

```shell
npm i @mediakind/mkplayer
```

サクッとインストールできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fb5bcae4-c684-44a2-d665-e86587a7aa42.png)

## 2.3. HTML 作成

ドキュメントに従って進みます。ほぼコピペ😎

まずは、MKPlayer のJavaScript と CSSの参照

```html
<head>
    <title>My Video Player</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- MKPlayer JavaScript and CSS -->
    <script  type="text/javascript"  src="./node_modules/@mediakind/mkplayer/mkplayer.js"></script>
    <link  rel="stylesheet"  href="./node_modules/@mediakind/mkplayer/mkplayer-ui.css">
</head>
```
そして、body に div タグ

```html
<body>
    <div id="video-container"></div>
</body>
```

HTML タグで、それぞれを囲って、現状は以下の感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3afcb72d-39ff-1491-6571-88844822e62f.png)


次に JavaScript で Player の初期化を行います。

```javascript
// 1. Grab the video container
const videoContainer = document.getElementById("video-container");

// 2. Prepare the player configuration
const playerConfig = {
    key: "PLAYER_LICENSE_HERE",
    playback: {
        muted: true,
        autoplay: true
    },
    // Subscribe to player events
    events: {
        [mkplayer.MKPlayerEvent.Error]: (event) => {
            console.log("Encountered player error: ", JSON.stringify(event));
        },
        [mkplayer.MKPlayerEvent.TimeChanged]: (event) => {
            console.log("Current player position: ", event.time);
        }
    }
};

// 3. Initialize the player with video container and player configuration
let player = new mkplayer.MKPlayer(videoContainer, playerConfig);
```

各種設定については MKPlayerConfig のドキュメントにあります。

https://mkplayer.azureedge.net/%24web/websdk/latest/docs/interfaces/MKPlayerConfig.html


ここでポイントなのが:

**key: "PLAYER_LICENSE_HERE"**

です。
MK/IO のポータルの [MKPlayer] のページから入手します。ここでは、動作確認を優先するために HTML コードに直接入力します。


:::note alert
警告!
- 今回作成した GitHub のリポジトリーは、速やかに**削除**することをおススメします。License Key が History として残ってしまうためです
- 本番環境で使う際には、API 化して設定するなどして、漏れないように保護してください。
:::

先ほどの図を再度掲載しますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/9cd00146-1f0c-66f3-5a1b-d367be13368a.png)

いよいよ 動画のURLを指定します。
HLS と DASH の両方ですね。

```javascript
const sourceConfig = {
    title: "It's time to Software Engineer!!!",
    description: "Software Engineer の皆さんへのメッセージ。可能性しかない!",
    hls: "https://ep-dahatakeorigin01-dahatakemediakindio.japaneast.streaming.mediakind.com/fa2b4e01-685f-4cd6-aef0-4733d7a513a5/Common_60.ism/manifest(format=m3u8-cmaf)",
    dash: "https://ep-dahatakeorigin01-dahatakemediakindio.japaneast.streaming.mediakind.com/fa2b4e01-685f-4cd6-aef0-4733d7a513a5/Common_60.ism/manifest(format=mpd-time-cmaf)"
};
```

そして、それを MKPlayer へ設定します。

```javascript
player.load(sourceConfig)
.then(() => {
    // you can also get notified when subscribed to `SourceLoaded` event.
    console.log("Source loaded successfull!");
})
.catch((error) => {
    console.error("An error occurred while loading the source!");
});
```

ドキュメントでは、この後クリーンアップをするコードがありますが、ここでは省略します。
Webアプリに組み込む際には、動画の入れ替えがある度にやったほうがいいと思います。つまりイベントハンドルをちゃんとやってね。という事ですね。

コードの全体はこちらです。

```html
<html>
<head>
    <title>My Video Player</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- MKPlayer JavaScript and CSS -->
    <script  type="text/javascript"  src="./node_modules/@mediakind/mkplayer/mkplayer.js"></script>
    <link  rel="stylesheet"  href="./node_modules/@mediakind/mkplayer/mkplayer-ui.css">
</head>

<body>
    <div id="video-container"></div>

    <script>
        // 1. Grab the video container
const videoContainer = document.getElementById("video-container");

// 2. Prepare the player configuration
const playerConfig = {
    key: "(内緒)",
    playback: {
        muted: true,
        autoplay: true
    },
    // Subscribe to player events
    events: {
        [mkplayer.MKPlayerEvent.Error]: (event) => {
            console.log("Encountered player error: ", JSON.stringify(event));
        },
        [mkplayer.MKPlayerEvent.TimeChanged]: (event) => {
            console.log("Current player position: ", event.time);
        }
    }
};

// 3. Initialize the player with video container and player configuration
let player = new mkplayer.MKPlayer(videoContainer, playerConfig);


const sourceConfig = {
    title: "It's time to Software Engineer!!!",
    description: "Software Engineer の皆さんへのメッセージ。可能性しかない!",
    hls: "https://ep-dahatakeorigin01-dahatakemediakindio.japaneast.streaming.mediakind.com/fa2b4e01-685f-4cd6-aef0-4733d7a513a5/Common_60.ism/manifest(format=m3u8-cmaf)",
    dash: "https://ep-dahatakeorigin01-dahatakemediakindio.japaneast.streaming.mediakind.com/fa2b4e01-685f-4cd6-aef0-4733d7a513a5/Common_60.ism/manifest(format=mpd-time-cmaf)"
};


player.load(sourceConfig)
.then(() => {
    // you can also get notified when subscribed to `SourceLoaded` event.
    console.log("Source loaded successfull!");
})
.catch((error) => {
    console.error("An error occurred while loading the source!");
});

    </script>
</body>
</html>
```

## 3. GitHub の リポジトリ作成

HTML ファイルをローカルで実行しても、MK Player は動作しません。
そのために、コスト面でもアプリケーションアーキテクチャの面でも理にかない過ぎている Azure Static Web Apps を使います。HTMLだけですからね。

https://learn.microsoft.com/ja-jp/azure/static-web-apps/

Azure Static Web Apps を使うためには、GitHub のリポジトリがあると便利です。Azure DevOps でもいいです。皆さんの使い慣れたほうを。

ここではGitHubを使います。

GitHub リポジトリーを作成してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/0e4efa1d-2b06-0772-ef27-b3c92351153a.png)

## 4. GitHub のリポジトリーのクローン

ローカル環境にクローンします。
コード書く前に本当はすべき事なんですがね😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/b9860ff3-1d34-04b9-615b-43508c7e1a1f.png)

ここでは GitHub Desktop を使います。Git Clone コマンドでも、何を使ってもいいんです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e5c5bf45-4103-f853-bd79-e1b2c547a625.png)

## 5. 作成したファイルのコピー

GitHub でローカルに持ってきたフォルダーに、先ほどまでの作業フォルダーからのファイルをコピーします。
その際、以下のファイルのコピーは避けます。GitHub Actions で不要なjobが作成されるのを避けるためです。

- package.json
- package-lock.json

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/653b2938-e5dc-fea3-0084-9dc73ebdf02c.png)

## 6. ローカルでのリポジトリーへのファイルのコミット。そして、プッシュ

ここでは、GitHub Desktop で行っています。
Visual Studio Code でもOK!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3faba1f4-7c94-5721-c394-39d40a8f41ec.png)

PUSH はファイルの数が多いので。私の環境では1分くらいかかりました。ネットの環境などに依存しますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/f4303af9-ab76-2512-671d-3032e1352cc8.png)

... README.md 作れば良かったっすね... お恥ずかしい😅

## 7. Azure Static Web Apps の作成

ポータルから作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/6492c4c6-5a13-1bac-544f-d97beb64d7b7.png)

ご参考まで...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/2621c4fb-94bd-f867-c45c-8e6a0111e3f1.png)

こちらが、デプロイのサンプルです。先ほど作成した GitHub のリポジトリーと連携させます。CDですね😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3f86d051-2c59-f856-8a51-1dcddfb97249.png)

作成を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/0eb805dc-3a3e-c70c-0ac5-c9e97e4d829f.png)

はい! 数分で出来ましたー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/3736a77b-2698-bafa-a5fe-5f07df2a8675.png)

GitHub との CD の状況は、Azure Static Web Apps の [デプロイ履歴] から確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/4efdd5fd-7561-1df7-c202-b568f8779381.png)

はい。GitHub の [Actions]から、CDの部分で実行されたジョブの確認ができますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/022f409e-b9c3-6577-7d9f-010a74d8c49f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/f3679274-068f-9772-3935-fa23ba549de4.png)


## 8. 動作確認

Azure Static Web Apps の[参照]からWebアプリを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/4aa51dc1-6311-2237-c087-98f563fdc821.png)

動きましたね!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/212c543d-a33c-529b-f836-9fb574ad546f.png)

ブラウザーでパケットを見てみましょう。
Windows 上でのMicrosoft Edge では、MPEG-DASH で通信されているのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/b14244a7-0ba2-7ba8-01a8-b62d3ad86860.png)

# まとめ

MKPlayer も、Azure Media Player 同様に、既存の HTML にタグを埋め込むだけで動作することがわかりました。
実際にアプリケーションに組み込む際には以下の実装が必要になる場合もあります。

- DRM/暗号化の実装
- APIからの MK Player 用の License Key 取得
- MK Player とのイベントのサブスクライブ

次回は CDN 連携ですね!