Video.js完全マニュアル part4 〜Video.jsの初期化〜

# はじめに
Video.js完全マニュアルとしてVideo.jsの解説をしていくシリーズのpart4です。
Video.jsの公式のガイドである[Video.js Guides](https://videojs.com/guides)を翻訳ツールを使いながら解説していきます。

前回はガイドの解説から外れて、Video.jsを初期化した時に何が起きているかを解説しました。今回はガイドの解説に戻り、Video.jsの初期化方法について解説していきます。

前回
[Video.js完全マニュアル part3 〜初期化で何が起きているのか？〜
](https://qiita.com/manzoku_bukuro/items/c4143663117c34cfc284)

part1から読む人は[こちら](https://qiita.com/manzoku_bukuro/items/10137f64810f0dc40543)

# この記事の対象者
- Video.jsを利用する人
- 動画プレイヤーのUI操作をしたい人
- 動画再生関連のサービスを作りたい人

# この記事の解説する章
[Video.jsの初期化](https://videojs.com/guides/setup/)

# Video.jsの初期化
## Video.jsの導入方法
Video.jsを導入する方法は、CDN読み込みをする方法とnpmでインストールする方法があります。

### CDN読み込み
2023年1月の最新のバージョンは7.20.3なので、最新バージョンを読み込みます。

```html
<link href="https://vjs.zencdn.net/7.20.3/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/7.20.3/video.min.js"></script>
```

### npm install
```bash
$ npm install --save-dev video.js
```

## Playerの作成
> ※ Video.jsでは<video>タグと<audio>タグの２つの要素に対応していますが、このガイドで扱うのは<video>タグだけとします。

### 埋め込みタグの用意

Video.jsをページに読み込んだら、Video.jsの呼び出しに必要な埋め込みタグを準備します。
`<video>`タグを利用する場合と、`<video-js>`タグを使う方法があります。

**タグについての特徴は以下の記事で説明しています。**
[Video.js完全マニュアル part2 〜Video.jsの埋め込みタグ種別紹介〜](https://qiita.com/manzoku_bukuro/items/ca8af6722ba647ab81f8)

どちらのタグを利用してもいいですが、`video`タグを利用する場合はプレイヤーが初期化されるまでに標準のコントローラーを表示してしまったりする場合があります。一方`<video-js>`タグの場合はそのようなことは起こりません。

### 自動初期化
埋め込みタグを用意してWebページの読み込みが完了した後に自動的に初期化が行われる方法です。
埋め込みタグ内に`data-setup`属性を付与します。

```html
<video class="video-js" data-setup='{}'>
    <source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
</video>
```

これで画面読み込み後に自動的に初期化が行われます。

### 手動初期化
自動初期化だと記述も少なく楽ですが、他の処理が完了後のタイミングでVideo,jsの初期化を行いたい場合は手動でスクリプトを記載して自分の意図したタイミングで初期化を実行する方法があります。
また最近のウェブではページの読み込み完了の段階で`<video>`要素が存在しない場合があります。その場合初期化は行われません。そのような事態を避けたい場合は手動で初期化をした方が良いでしょう。

#### idを渡す初期化方法

```html
<video　id="my-player" class="video-js">
    <source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
</video>
```
以上のように埋め込みタグに`my-player`というidを割り振ったとします。

```js
videojs('my-player');
```
script部分でidを渡して`videojs()`メソッドを実行することで初期化が完了します。

#### DOM要素を渡す初期化方法
埋め込みタグにidを振って`videojs()`メソッドを実行する以外でも、埋め込みタグのDOM要素を渡して初期化を実行する方法があります。

```html
<video　class="video-js">
    <source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
</video>
```
以上のように埋め込みタグにidが付与されていないとします。

```js
const videoJsDom = document.querySelector('.video-js');
videojs(videoJsDom);
```
以上のようにDOM要素を渡して`videojs()`メソッドを実行することで初期化が完了します。

### Playerのデータの参照方法
Video.jsによって初期化後にPlayerが作成されると、Video.jsはPlayerのデータを参照出来るようになります。
参照方法はいくつかあるので紹介します。

#### videojs()メソッドの戻り値を利用する
`videojs()`利用してPlayerを生成すると、戻り値でPlayerのデータが渡されるので、それを変数に代入することで変数を利用してPlayerのデータを参照出来ます。
```js
const video = videojs('video1', {});
console.log(video);
```

また、既に生成されてあるPlayerと同一のidやDOM要素を渡して`videojs()`メソッドを実行すると、別のPlayerが生成されるのではなく既存のPlayerのデータが返ってくるだけです。
```js
videojs('video1', {});
const video = videojs('video1', {}); // idがvideo1のPlayerのデータを返すだけ
```

この方法でPlayerのデータを参照しようとした場合、仮に何か不具合で既にある想定のPlayerが存在しない場合は再度生成を試みてしまうので、予期せぬ挙動をしてしまうかもしれません。

#### getPlayer()メソッドを利用する
Video.jsが用意する`getPlayer()`メソッドを使用する方法です。
初期化と同じように既存PlayerのidかDOM要素を渡すことで、Playerが存在する場合はPlayerのデータを返却します。存在しなければundefinedを返します。
```js
const video = videojs.getPlayer('video1');
console.log(video);
```

#### videojs.getPlayer()メソッドを利用する
Video.jsが用意する`getPlayer()`メソッドを使用する方法です。
初期化と同じように既存PlayerのidかDOM要素を渡すことで、Playerが存在する場合はPlayerのデータを返却します。存在しなければundefinedを返します。
```js
const video = videojs.getPlayer('video1');
console.log(video);
```

#### videojs.getPlayers()メソッドもしくはvideojs.playersプロパティを利用する
`getPlayer()`メソッドが引数が必要だったのに対し、`getPlayers()`メソッドは引数が必要がありません。
`getPlayers()`メソッドを実行すれば存在する全てのPlayerを配列で返却します。
また、`videojs.players`プロパティにアクセスしても同様の結果が得られます。
```js
const videos = videojs.getPlayers();
console.log(videos['video1']);
// もしくは videojs.players
```

連想配列で格納されていて、キー名はPlayer生成時のidとなっています。idを付与せずに生成した場合は自動でidが割り振られています。

### 初期化時のオプションの渡し方
初期化時にオプションを渡すことで、生成後のPlayerの挙動を変えたり見た目を変えることが出来ます。オプションの詳細については次回の記事で説明します。
この記事ではオプションの渡し方のみ解説します。

#### videoタグの属性として渡す
標準のvideoタグと同じようにvideoタグの属性としてオプションを渡す方法です。
```html
<video controls autoplay preload="auto" ...>
```

しかし標準のvideo属性で使われていないオプションは利用することが出来ません。

##### videoタグの属性でオプションを渡す場合の注意
多くの属性はbooleanなので、値を指定するべきではありません。属性が存在する場合は真値、存在しない場合は偽値を意味するのが正しいとされています。

**間違った指定**
```html
<video controls="true" ...>
<video loop="true" ...>
<video controls="false" ...>
```

**正しい指定**
```html
<video controls ...>
<video loop="loop" ...>
<video ...>
```

#### videoタグのdata-setup属性として渡す
自動初期化時に使われるdata-setup属性でオプションを渡す方法です。JSONとして渡します。
```html
<video data-setup='{"controls": true, "autoplay": false, "preload": "auto"}'...>
```
この方法ならvideo属性にないオプションも渡すことが出来ます。

**注意: jsonとして渡すので、シングルクォーテーションとダブルクォーテーションの使い分けに気をつけましょう**

#### videojs()メソッドの第二引数でオプションオブジェクトを渡す
最後の方法は`videojs()`メソッドの第二引数にオプションオブジェクトを渡す方法です。
```js
videojs('my-player', {
    controls: true,
    autoplay: false,
    preload: 'auto'
});
```
**注意: data-setupとオプションオブジェクトを同時に使用しないようにしましょう**

#### オプションのグローバル設定
生成時にオプションを渡すことも出来ますが、生成前にオプションのグローバル設定を行うことが出来ます。
```js
videojs.options.autoplay = true;
```

以下のようにグローバル設定を行った後は、以降生成されるPlayerは全て指定のオプションが適用されます。

### 初期化を検知する
Video.jsは非同期に初期化が実行されるので、初期化前にPlayerの参照をしようとしてデータの取得に失敗することがあります。
なのでPlayerが生成完了しているかどうかを検知する方法があるので紹介します。

#### videojs()メソッドの第三引数にコールバック関数を渡す
`videojs()`メソッドの実行時に第二引数でオプションを渡しましたが、第三引数にコールバック関数を渡すことでPlayer生成後に処理を実行することが出来ます。
```js
videojs('my-player', null, () => {
    // Player生成後に実行したい処理
});
```
オプションの指定がない場合は`null`を渡せば、第三引数にコールバック関数を渡すことが出来ます。

#### ready()メソッドでコールバック関数を渡す
Playerの参照を行う変数を利用して、`ready()`メソッドを実行することで、Playerの初期化を待機して処理を実行することが出来ます。
```js
const player = videojs('my-player');

player.ready(() => {
    // Player生成後に実行したい処理
});
```

#### readyイベントを検知する
Playerの参照を行う変数を利用して、readyイベントを検知する方法です。
addEventlistenerのようにonメソッドを使うことでイベントを検知することが出来ます。readyイベントを検知することで、プレイヤー生成後に処理を実行することが出来ます。

```js
const player = videojs('my-player');

player.on('ready', () => {
    // Player生成後に実行したい処理
});
```
# 最後に
Video.jsの初期化について説明しました。
次回は初期化時に渡すオプションについて詳しく説明します。

---
[Twitter](https://twitter.com/manzoku_bukuro)もやってます