iframe Player API と CSS を使って YouTube 動画を拡大表示する

## 概要
YouTube の提供する iframe Player API と CSS を使って YouTube の動画をWEBサイト上で拡大表示する方法をご紹介します。 

## 環境
jQuery: 2.2.4

## iframe Player API とは
iframe Player API（以下 iframe API） はWEBページ上に動的に ```iframe``` タグを生成し、YouTube の動画を読み込むことができる JavaScript の API です。
また、一度読み込んだ動画は専用の関数を使って再生や停止などの制御をすることも可能です。

今回のように、同じ場所に複数の動画を切り替えて表示したり、自前で再生/停止などの制御を行いたいときなどにはこの API を使うとそれらの処理を簡単に書くことができます。

## 実装
今回はページに動画のサムネイルを３つ並べて表示し、サムネイルをクリックしたら画面いっぱいに背景が黒のウィンドウを表示して、その真ん中にクリックしたサムネイルに対応する YouTube の動画を表示するコードを書いてみたいと思います。

### HTML/CSS
まずは HTML と CSS のコードを記載します。

``` index.html
<body>
    <div class="container">
        <div class="movies">
            <img class="mv_thumb" src="./img/thumb01.png" alt="" data-id="1つ目の動画のid">
            <img class="mv_thumb" src="./img/thumb02.png" alt="" data-id="2つ目の動画のid">
            <img class="mv_thumb" src="./img/thumb03.png" alt="" data-id="3つ目の動画のid">
        </div>
    </div>
    <div class="movie_view_pop">
        <div class="wrapper">
            <div class="close">
                <div class="border1"></div>
                <div class="border2"></div>
            </div>
            <div id="player"></div>
        </div>
    </div>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script type="text/javascript" src="https://www.youtube.com/iframe_api" ></script>
    <script src="js/main.js"></script>
</body>

```

``` style.css
@charset "utf-8";

.container {
    width: 80%;
    margin: 0 auto;
}

.movies {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.movies img {
    width: 30%;
}

.movie_view_pop {
	background: rgba(0, 0, 0, 0.8);
	display: flex;
	align-items: center;
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	padding: 20px;
	z-index: 999;
	visibility: hidden;
	opacity: 0;
	transition: all 0.8s;
}

.movie_view_pop.visible {
	visibility: visible;
	opacity: 1;
}

.movie_view_pop .wrapper {
	width: 80vw;
	height: 80vh;
	margin: 2rem auto;
	position: relative;
}

.movie_view_pop iframe {
	display: block;
	width: 100%;
	height: 100%;
}

.movie_view_pop .close {
	position: absolute;
	top: 0;
	right: -60px;
	z-index: 9999;
	height: 40px;
	width: 40px;
	cursor: pointer;
}

.movie_view_pop .border1, .movie_view_pop .border2 {
	width: 40px;
	height: 2px;
	background: #fff;
}

.movie_view_pop .border1 {
	transform: rotate(45deg) translate(13px, 13px);
}

.movie_view_pop .border2 {
	transform: rotate(135deg) translate(12px, -12px);
}

```

```.movies``` の直下に再生したい動画のサムネイルを並べます。
見た目はこんな感じです。（画像にモザイクがかかっていますが、サムネイルだと思ってください）
![スクリーンショット 2022-10-13 171145.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261074/ac4c376b-77d8-7624-a45c-806c74ef6690.png)

各サムネイルの ```data``` 属性には動画の id を埋め込んでいます。
id は YouTube 動画のURLの「watch?v=」より後の部分に付いている文字列です。
例えば、動画のURLが「 https://www.youtube.com/watch?v=q-TJnkW18n4 」なら id は「q-TJnkW18n4」になります。
※上記は弊社の動画です。

そしてサムネイルをクリックすると ```data``` 属性に設定した id を持つ動画を iframe API を使って読み込み、拡大表示します。
```.movie_view_pop``` は動画の拡大表示専用のウィンドウです。（デフォルトでは非表示にしています）
このウィンドウを表示すると動画を含めて以下のような見た目になります。
![スクリーンショット 2022-10-13 171255.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261074/a7ffbf9b-2c97-0628-8416-737a1d065720.png)

右上の「×」ボタン（```.close```）クリックで動画と共に拡大表示ウィンドウを非表示にします。
この時ウィンドウをふわっと消したいので、```display``` ではなく ```visibility``` で表示/非表示を制御しています。

また、```<div id="player"></div>``` は iframe API によって ```iframe``` タグに変わる部分になります。（上の画像で動画が表示されている部分です。詳しくは後述します。）

### JavaScript
まず iframe API を自作の JavaScript のコード（```main.js```）より先に読み込みます。
なお、HTMLに直接書かずに公式ドキュメントのように JavaScript のコードによって読み込んでも問題ありません。

```
<script type="text/javascript" src="https://www.youtube.com/iframe_api" id="js_youtube_iframe_api-js"></script>
<script src="main.js"></script>
```
次に JavaScript のコードで iframe API を呼び出します。

``` main.js
$(function(){	
	var player = null;
	window.onYouTubeIframeAPIReady = function () {
		$('.mv_thumb').on('click', function () {
			
			$( '.movie_view_pop').addClass('visible');
			$('html').css('overflow', 'hidden');
			player = new YT.Player('player', {
				videoId: $(this).data('id'),
				events: {
					'onReady': onPlayerReady
				}
			});
		});
	}

	function onPlayerReady(event) {
		event.target.playVideo();
	}
	
	$('.movie_view_pop .close').on('click', function(){
		player.stopVideo();
		player.destroy();
		player = null;
		$( '.movie_view_pop').removeClass('visible');
		$('html').css('overflow', 'scroll');
	});
});

```
iframe API の読み込みが終わると  API によって　```window.onYouTubeIframeAPIReady``` 関数が自動で読み込まれます。
そこにサムネイルをクリックすると動画拡大表示用のウィンドウを開くとともに、動画再生の準備を行うコードを書いていきます。

#### 動画再生の準備

``` main.js
player = new YT.Player('player', {
  videoId: $(this).data('id'),
  events: {
    'onReady': onPlayerReady
  }
});
```
```player``` 変数に初期化した　```YT.Player``` オブジェクトを代入します。
このオブジェクトは初期化と同時に第一引数に指定したタグを ```iframe``` タグに置き換えます。
今回は ```'player'``` を指定しているため　```<div id="player"></div>```　が ```iframe``` タグに置きかわります。
また、この引数は ```id``` 属性の値でなくてはなりません。（```class``` 属性の値は不可です）

第二引数ではオブジェクトの中に動画再生に必要な各種プロパティを設定します。

```videoId```: 
YouTubeの動画を識別する id です。
動画の id はクリックした ```img``` タグの ```data``` 属性から取得しています。

```events```: 
各種イベント発火時に実行したい関数を指定します。
今回は動画再生の準備が完了した時に発火する ```onReady``` に自作の ```onPlayerReady()``` 関数を指定しています。
他のイベントとしてはエラー発生時に発火する ``` onError``` や「再生中」「停止」といった動画の状態が変化した時に発火する ```onStateChange``` などがあります。

また今回は書いていませんが、ループ再生の設定やコントロールバーを非表示にするなどのカスタマイズが必要なときは ```playerVars``` プロパティで指定が可能です。

#### 動画の再生
``` main.js
function onPlayerReady(event) {
  event.target.playVideo();
}
```

```Player``` オブジェクトの ```onReady``` に設定した関数です。
引数の ```event``` でイベントそのものを受け取り、```event.target``` で ```Player``` オブジェクトを取得します。
今回は ```Player``` オブジェクトの ```playVideo()``` メソッドを実行することにより動画の読み込みが完了した時点で再生を自動で開始するようにしています。

ちなみにスマホ端末ではこの処理を書いていても、ユーザーが再生ボタンを押さない限り再生が始まらない場合があるのでご注意ください。

#### 動画の終了

``` main.js
$('.movie_view_pop .close').on('click', function(){
		player.stopVideo();
		player.destroy();
		player = null;
		$( '.movie_view_pop').removeClass('visible');
		$('html').css('overflow', 'scroll');
	});
});
```

ユーザーが「×」ボタン（```.close```）を押した時の処理です。

```stopVideo()``` によって再生中であっても動画を停止し、```destroy()``` で ```iframe``` タグを削除します。
また、```player``` 変数に ```null``` を代入することで変数を ```Player``` オブジェクトから解放します。

そして拡大表示用のウィンドウ（```.movie_view_pop```）を非表示にします。

## 参考
https://developers.google.com/youtube/iframe_api_reference?hl=ja#Playback_controls