今までJW Playerを使っていたけどplyr.jsをカスタマイズしてみた（３）

# 前回まで
[前回まで] (https://qiita.com/nishidataishi/items/666305bf13983169524f) でボタンの色や配置をカスタマイズすることはできました。
ここからは独自のボタンを追加するなどさらなるカスタマイズに進みます。

# オリジナルのボタン追加
下記の公式情報のように、HTMLをJavaScriptにガシガシ書くことで追加できます。

```js:公式の情報
const controls = `
<div class="plyr__controls">
    <!-- もう一度再生ボタン -->
    <button type="button" class="plyr__control" data-plyr="restart">
        <svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Restart</span>
    </button>
    <!-- 10秒戻るボタン -->
    <button type="button" class="plyr__control" data-plyr="rewind">
        <svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
    </button>
    <!-- 再生、停止ボタン -->
    <button type="button" class="plyr__control" aria-label="Play, {title}" data-plyr="play">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
    </button>
    <!-- 10秒進むボタン -->
    <button type="button" class="plyr__control" data-plyr="fast-forward">
        <svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
    </button>
    <!-- プログレスバー -->
    <div class="plyr__progress">
        <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
        <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
        <span role="tooltip" class="plyr__tooltip">00:00</span>
    </div>
    <!-- 現在時間 -->
    <div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
    <!-- 全体の再生時間 -->
    <div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
    <!-- ミュート、ミュート解除ボタン -->
    <button type="button" class="plyr__control" aria-label="Mute" data-plyr="mute">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
    </button>
    <!-- ボリューム -->
    <div class="plyr__volume">
        <input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" aria-label="Volume">
    </div>
    <!-- 字幕表示/非表示ボタン -->
    <button type="button" class="plyr__control" data-plyr="captions">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
    </button>
    <!-- フルスクリーンボタン -->
    <button type="button" class="plyr__control" data-plyr="fullscreen">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
    </button>
</div>
`;

// 「controls:」はいらない
const player = new Plyr('#player', { controls });
```
実はこの方法

2つ制約があり

- ピクチャーインピクチャとAirPlayは追加できるが、ブラウザが対応しているのかは自分で実装する必要がある。
- **設定メニューは非対応**。

そうなのです。画質変更、再生速度変更などの設定メニューはこの方法では**自分で実装するしかない**のです。
再生速度は「plaer.speed=2」のように瞬殺だったのですが、画質変更がえげつなく難しかったです。
ただ、出来てしまえば「まあ、当然ですよね。」という内容でした。

``` js:myplayer.js
// 画質ごとの動画ファイルのパスを格納する変数
var video_url 1080 = "video/file_1080p.mp4";
var video_url 720 = "video/file_720p.mp4";
var video_url 480 = "video/file_480p.mp4";

$(function() {
  const controls = `
<div class="plyr__controls">
    <!-- もう一度再生ボタン -->
    <button type="button" class="plyr__control" data-plyr="restart">
        <svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Restart</span>
    </button>
    <!-- 10秒戻るボタン -->
    <button type="button" class="plyr__control" data-plyr="rewind">
        <svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
    </button>
    <!-- 再生、停止ボタン -->
    <button type="button" class="plyr__control" aria-label="Play, {title}" data-plyr="play">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
    </button>
    <!-- 10秒進むボタン -->
    <button type="button" class="plyr__control" data-plyr="fast-forward">
        <svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
        <span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
    </button>
    <!-- プログレスバー -->
    <div class="plyr__progress">
        <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
        <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
        <span role="tooltip" class="plyr__tooltip">00:00</span>
    </div>
    <!-- 現在時間 -->
    <div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
    <!-- 全体の再生時間 -->
    <div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
    <!-- ミュート、ミュート解除ボタン -->
    <button type="button" class="plyr__control" aria-label="Mute" data-plyr="mute">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
    </button>
    <!-- ボリューム -->
    <div class="plyr__volume">
        <input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" aria-label="Volume">
    </div>
    <!-- 字幕表示/非表示ボタン -->
    <button type="button" class="plyr__control" data-plyr="captions">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
    </button>
    <!-- フルスクリーンボタン -->
    <button type="button" class="plyr__control" data-plyr="fullscreen">
        <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
        <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
        <span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
        <span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
    </button>
    <!-- 画質選択ボタン -->
    <button type="button" class="plyr__control" data-plyr="settings" id="plyr_quality">
        <span class="plyr__label">480</span>
        <span class="plyr__tooltip" role="tooltip">画質選択</span>
    </button>
    <div id="quality_menu" class="hidden pa tc">
      <div val="1080" class="quality_select cp">1080p</div>
      <div val="720" class="quality_select cp">720p</div>
      <div val="480" class="quality_select cp">480p</div>
    </div>
</div>
`;

  // 「controls:」はいらない
  const player = new Plyr('#player', { controls });

  // 画質ごとのファイルをsourceに設定
  player.source = {
      type: "video",
      sources: [
        { src: video_url_480, type: "video/mp4", size: 480 },
        { src: video_url_720, type: "video/mp4", size: 720 },
        { src: video_url, type: "video/mp4", size: 1080 }
      ],
      poster: overview_url
  };

  // 最初は画質リストは非表示
  $("#quality_menu").hide();

  // 画質選択ボタンの動作を追加
  $("#plyr_quality").click(function() {
    // 画質リストを表示
    $("#quality_menu").toggle();
  });

  // 画質リストから選択した時の動作
  $(".quality_select").click(function() {
    // 経過時間を取得
    cur_time = player.currentTime;
    setPlayerSource(player, $(this).attr("val"));
    // 0秒以上なら再生されているとみなして、同じ時間から再生
    if (cur_time > 0) {
      player.play();
      player.currentTime = Number(cur_time);
    }
    $("#quality_menu").hide();
  });
});

function setPlayerSource(player, cur_val) {
  if (cur_val == "1080") {
    player.media.src = video_url;
  } else if (cur_val == "720") {
    player.media.src = video_url_720;
  } else {
    player.media.src = video_url_480;
  }
}
```
そうです。要するにやっていることは「**video要素のsrc属性を変える**」だけです。
ただ、私の英語力の問題か、公式の文書から「playerのmediaプロパティにvideo要素が入っている」ということが読み解けなかったので、単純にコンソールで色々いじって見つけました。
なので、公式推奨のやり方ではないです。

そうするとこのように表示されます。
<img width="1439" alt="スクリーンショット 2020-08-02 10.20.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118515/2d8b92b8-15cf-abef-c75c-5838332fa823.png">
見た目がものすごいイマイチです...。

```js:myplayer.js
// ... 略

    <div class="plyr__progress" style="width:100%;">
        <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
        <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
        <span role="tooltip" class="plyr__tooltip">00:00</span>
    </div>

// ... 略

    <div id="quality_menu" style="position: absolute; top: -50px; background: red;">
      <div val="1080" class="quality_select cp">1080p</div>
      <div val="720" class="quality_select cp">720p</div>
      <div val="480" class="quality_select cp">480p</div>
    </div>
```
とりあえず上記2箇所だけ修正すればプレイヤーっぽくなって、画質メニューを開いても幅がずれたりはしなくなります。
<img width="1440" alt="スクリーンショット 2020-08-02 10.29.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118515/f16838f2-afc2-ebea-7dbb-0592b0825300.png">

参考リンク：
公式のコントローラーの説明
https://github.com/sampotts/plyr/blob/master/CONTROLS.md