動画をwebに実装するときのメモ（video, youtube API, vimeo API）

#動画をwebに実装するときのメモ
動画の実装に馴染みがなかったので浅く調べたメモとAPIなど各実装時のパラメーターやイベントのまとめや複数設置や実装してみてわかったメモ

## 特徴
### video 要素
#### メリット
- コンテンツの一元管理ができる
- 自由なサイズで埋め込み可能

#### デメリット
- 自前のサーバーに置くので負荷の心配

### Youtube
#### メリット
- 自前のサーバーに依存しない
- 共有性が高い
- youtubeからや共有先などからの流入経路に期待が持てる
- SEOに強い（動画単体でインデックスされるので検索で動画の方が上位表示されることもある）

#### デメリット
- 意図せぬユーザーからのコメント等
- サーバーが自前じゃ無いから不慮の事態（動画だけ遅いとか）の復旧等はプラットフォーム依存
- 停止状態の時の「youtube」のロゴだけはどうやっても消せない

※静止した時にyoutubeのサムネイルではなくオリジナルのサムネイルを用意してかぶせて隠して回避する

- 比率が一定なので縦長い動画を設置したい時、横に黒いふちがつく（サイト上の埋め込み時はサイズ指定で解消する）

※ちなみにあの黒い縁はウインドウボックスと言うらしい
https://support.google.com/youtube/answer/118277?hl=ja

※Youtubeの埋め込みiframeは複数設置の場合、インラインでミュート設定しても同時自動再生はできないのでやりたい場合はIFrame Player APIを使う

### vimeo
#### メリット
- 自前のサーバーに依存しない
- 動画コントローラーのカスタマイズ性が高い
- 自由なサイズで埋め込み可能

#### デメリット
- インライン再生ができない（iOS Safariで自動再生はできない）
- サーバーが自前じゃ無いから不慮の事態（動画だけ遅いとか）の復旧等はプラットフォーム依存

## 基本メモ

### レスポンシブ対応とアスペクト比固定
```html:html
<div class="video-wrap">
    <video id="video01" loop muted playsinline>
        <source src="./video/01.mp4" type="video/mp4" />
    </video>
</div>
```

```scss:scss
.video-wrap {
  position: relative;
  width: 100%;// デザインにより調整
   &:before {
    content: "";
    display: block;
    width: 100%;
    padding-top: 56.25%;// =高さの比率（9） / 幅の比率（16） *100%　（※オリジナルの比率の場合は高さ　/　幅　*　100%）
  }
  #video01 {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}
```

### iOS10以降対応自動再生
条件は

- インライン再生であること
- 無音状態（ミュート）であること


```html:html
<video id="video01" loop muted playsinline>
    <source src="./video/01.mp4" type="video/mp4" />
</video>
```
参考
[iOS10 Mobile Safariにおけるビデオの自動再生](https://qiita.com/hayakix/items/4c841ea76eab70a66e91)

iOS10よりバージョンが低い場合
[Safari HTML5 Audio and Video Guide](https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html)
User Control of Downloads Over Cellular Networks部分参照
> In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.
>> 携帯電話回線での閲覧は通信容量を消費するので課金されちゃうからユーザーに無断でのDLは推奨してしないんでユーザーがアクション起こさないと押さないと再生させないからね！（意訳）

*自動再生が可能になったといって、ユーザビリティを考えると乱用はおすすめしません。

### 中国での規制
youtube、viemo等は中国で規制されているので、ローカライズが必要なサイトには向かず、実装した場合、極端にサイトの読み込みが遅くなるか表示されないらしい。

[中国のネット検閲:Wikipedia](https://ja.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E6%A4%9C%E9%96%B2)

### IEでz-indexが効かない（youtube）
オリジナルのサムネイルを作成し動画の上にかぶせる場合などで発生するのでwmode=transparentを付与して対応する

```html:埋め込みiframeの場合
<iframe src="http://www.youtube.com/embed/動画ID?wmode=transparent"></iframe>
```

```js:iframePlayerApiの場合
var player = new YT.Player(id, {
    ~ 中略 ~
    playerVars: {
        wmode : "transparent"
    }
});
```

参考：
[Youtubeでもz-indexが効くようにする「?wmode=transparent」パラメーターをjQueryで自動挿入する](http://kachibito.net/web-design/youtube-zindex-with-jquery.html)
[レガシーIEでのYouTube（iframe）対応](https://qiita.com/naota70/items/b875d35674ab80b7ca74)

## 基本実装
共通前提：インライン、ミュート、自動再生。jsはjquery使用
複数の場合の前提：同上 + 並べて順番に再生

※メモリやらCPUやら通信容量やらをくっちゃうので延々流すのはよろしくないですが、こういう案件があったので＞＜

### video 要素
パラメータは要素に付与する
参考：[video 要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/video)

#### 単体
```html:html
<video id="player" autoplay loop muted playsinline width="100%">
    <source src="./video/hoge.mp4">
</video>
```
#### 複数設置
```html:html
<video id="player01" autoplay muted playsinline width="100%">
    <source src="./video/hoge01.mp4">
</video>

<video id="player02" muted playsinline width="100%">
    <source src="./video/hoge02.mp4">
</video>
```

```js:js
$(function () {
    $('#player01').on('ended', function () {// player01終了
        $('#player02').get(0).play();
    });

    $('#player02').on('ended', function () {// player02終了
        $('#player01').get(0).play();
    });
});
```
上記を元に必要な処理を入れていく

```js:例：全部で5回ループしたら終了
$(function () {
    var cnt = 0;

    $('#player01').on('ended', function () {// player01終了
        cnt++;
        if (cnt < 5) {// 全てのループは5回まで
            $('#player02').get(0).play();
        } else {
            $('#player01').get(0).autoplay=false;
            //console.log('全ループ終わったよ');
        }
    });

    $('#player02').on('ended', function () {// player02終了
        $('#player01').get(0).play();
    });
});
```

多くなったらまとめちゃう

```js:配列苦手なので自分用メモ
$(function () {
    for (var i = 1; i <= 2; i++)
    {
        (function() {
            var videoIndex = (i != 2) ? (i + 1) : (1);
            var next = $("#player0" + videoIndex);

            $("#player0" + i).on("ended", function() {
                next.get(0).play();
            });
        })(i);
    }
});
```
endedやseekedなど状態を取得するイベントが用意されてる
参考：[video要素、audio要素をJavaScriptから操作する](http://www.htmq.com/video/)

### youtube
iframe player api使用
#### 単体
```html:html
<div id="player"></div>
```

```js:js
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var ytPlayer;

function onYouTubeIframeAPIReady() {
    ytPlayer = new YT.Player('player', {
        height: 390,
        width: 640,
        videoId: 'vifZUxk2WgI',
        playerVars: {//パラメータ
          playsinline: 1,// インライン再生指定
          rel      : 0,// 再生中の動画と同じチャンネルの関連動画を表示
          controls: 0,// コントローラー出さない
          showinfo: 0// タイトルとか動画情報出さない
        },    
        events: {//　イベント
            'onReady': onPlayerReady
        }
    });
}

function onPlayerReady() {
  ytPlayer.mute();// ミュートにしてから
  ytPlayer.playVideo();// 再生
}
```

onStateChangeで状態取得する時のサンプルは下記
[サンプル:CodePen](https://codepen.io/ta-ke-no-bu/pen/NwLELz)

### 複数
```html:html
<div id="player"></div>
<div id="player1"></div>
```
```js:js
// API 読み込み
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var ytPlayer, ytData, ytPlaying, ytStop, ytPlay;

ytPlayer = [];
ytData = [// 呼び出したい動画と表示したい箇所のIDを設定
  {id: 'hEkexHJJdHc', area: 'player'},
  {id: 'L6ZrKPMzOmg', area: 'player1'}
];

function onYouTubeIframeAPIReady() {
  for(var i = 0; i < ytData.length; i++) {
    ytPlayer[i] = new YT.Player(ytData[i]['area'], {
      videoId: ytData[i]['id'],
      playerVars: {
        playsinline: 1,// インライン再生指定
        rel      : 0,// 再生中の動画と同じチャンネルの関連動画を表示
        controls: 0,// コントローラー出さない
        showinfo: 0// タイトルとか動画情報出さない
      }  ,    
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });
  }  
}

function onPlayerReady(e) {
  ytPlayer[0].mute();
  ytPlayer[0].playVideo();//1個目の動画を再生
}

function onPlayerStateChange(e) {
  var state, target;
  state = e.target.getPlayerState();
  target = e.target.getIframe().id;
  if(state == 0) {// 終了した時
    ytPlayer[1].mute();
    ytPlayer[1].playVideo();//2個目の動画を再生
  }
}

```

パラメータ：[YouTube 埋め込みプレーヤーとプレーヤーのパラメータ](https://developers.google.com/youtube/player_parameters?playerVersion=HTML5&hl=ja)
イベント：[IFrame Player API イベント](https://developers.google.com/youtube/iframe_api_reference?hl=ja#Events)
※targetでプレイヤー識別可能。複数ある場合はgetIframeでid取得して識別
※onReady以外はgetPlayerStateで状態を取得できる。

onStateChangeで状態取得するサンプルと再生終了したら次の動画を再生するサンプルは下記
[サンプル:CodePen](https://codepen.io/ta-ke-no-bu/pen/EbeeLm)


##### よく使いそうなイベント

- onReady 読み込み完了
- onStateChange プレイヤーの状態が変わった時
- onError　プレイヤーがエラーになった時　など

### vimeo
vimeo API使用。
インライン再生にするパラメータが無い（見つからなかった）ので前提からインライン再生を除く
共通前提：ミュート、自動再生（iOS safari以外）
複数の場合の前提：同上 + 並べて順番に再生

※ある程度再生したら勝手に止まるようなので延々流したかったら（やらない方がいいですが）工夫が必要

#### 単体
```html:html
<div id="player"></div>
(中略)
<script src="//player.vimeo.com/api/player.js"></script>
```

```js:js
$(function() {
    // プレーヤーのオプション設定
    var options = {
        id: 198853598, // VimeoのID
        autoplay: true, // 自動再生
        byline: false, // 投稿者の表示
        portrait: false, // Vimeoロゴの表示
        color: 'ff0000', // プレーヤーのカラー        
        title: false // 動画タイトルの表示
    };
 
    var player = new Vimeo.Player($('#player'), options);

    player.setVolume(0); // ミュート
    player.play();//　再生
});
```



```html:データ属性でオプション設定も可能
<div id="player" data-vimeo-id="198853598" data-vimeo-autoplay="true" data-vimeo-byline="false" data-vimeo-portrait="false" data-vimeo-color="ff0000" data-vimeo-title="false"></div>

```


#### 複数
```html:html
<div id="player01"></div>
<div id="player02"></div>
```
```js:js

$(function() {
    // プレーヤーのオプション設定
    var options = {
        id: 198853598, // VimeoのID
        autoplay: true, // 自動再生させる
        byline: false, // 投稿者の表示
        portrait: false, // Vimeoロゴの表示     
        title: false, // 動画タイトルの表示
        autopause: true// 他のプレーヤーを一時停止にするかどうか
    };
    var options2 = {
        id: 203299850, // VimeoのID
        autoplay: false, // 自動再生させないでplayer01の再生終了をトリガーにする
        byline: false, // 投稿者の表示
        portrait: false, // Vimeoロゴの表示     
        title: false, // 動画タイトルの表示
        autopause: true// 他のプレーヤーを一時停止にするかどうか
    };
 
    var player01 = new Vimeo.Player($('#player01'), options);
    var player02 = new Vimeo.Player($('#player02'), options2);

    player01.setVolume(0); // ミュート
    player01.play();
    console.log('player01再生中1回目');
  
    player01.on('ended', function(data) {// player01を最後まで再生した時
        player02.setVolume(0);
        player02.play();
        console.log('player02再生中');
    });
  
    player02.on('ended', function(data) {// player02を最後まで再生した時
        player01.setVolume(0);
        player01.play();
        console.log('player01再生中');
    });
});

```



パラメータ:[Vimeo Player API -> Embed Options](https://github.com/vimeo/player.js#embed-options)
イベント:[Vimeo Player API -> Events](https://github.com/vimeo/player.js#events)
メソッド:[Vimeo Player API -> Methods](https://github.com/vimeo/player.js#methods)

[Vimeo複数サンプル:CodePen](https://codepen.io/ta-ke-no-bu/pen/qVvOKy)