YouTube Player APIを使って動画を同時視聴できるサイトを作った

##概要
YouTube Player APIを使って、youtubeの動画を同時視聴できるサイトを作ります
URLを入力すると入力したURLの数だけページに埋め込まれたyoutubeの動画が再生されます
##使うもの
- javascript(メイン)
- HTML
- CSS

サイトを作るのでこの3つでできます
##YouTube Player APIとは
YouTube Player APIはjavascriptを使ってページにyoutubeの動画を埋め込むことができるAPIです
https://developers.google.com/youtube/iframe_api_reference?hl=ja
公式のリファレンスはこちらですが、個人的には下のページの解説がわかりやすかったです
https://www.tam-tam.co.jp/tipsnote/javascript/post6217.html
HTMLのタグをjavascriptで指定してそこに埋め込みます
##step1 URLを入力するページを作る
まずはHTMLでページの骨組みを作っていきます
URLを入力するページと入力されたURLの動画を埋め込むページの2つが必要なのでまずはURLを入力するページを作っていきます

```HTML:index.html
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" type="text/css" href="form.css">
	<link rel="stylesheet" type="text/css" href="button.css">
	<title>Multiyoutube-inputpage</title>
</head>
<body>
	<form name='mainForm' action="result.html" method="get">  
	  <div>
	    <h3>inputURL</h3>
	    <input name='u1' type='text'>
	    <input name='u2' type='text'>
	    <input name='u3' type='text'>
	    <input name='u4' type='text'>
	    <input name='u5' type='text'>
	  </div>
	  <input type="submit" value="submit" class="btn-flat-border">
	</form>
</body>
</html>
```
formを使って5つのinputに入力されたURLが後に紹介するresult.htmlに渡されます
##step2 動画を埋め込むページを作る
URLを入力するページは作ったので、動画を埋め込むページを作ります

```HTML:result.html
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" type="text/css" href="result.css">
	<link rel="stylesheet" type="text/css" href="button.css">
	<title>Multiyoutube</title>
</head>
<body>
	<div id="videos"></div>
	<p><a href="index.html" class="btn-flat-border">back to input page</a></p>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	<script src="sample.js"></script>
</body>
</html>
```
javascriptで埋め込むのでこのページはシンプルです
##step3 CSSを書く
サイトとしてアップロードするので、あまりに殺風景だとあれなのでちょこっとCSSを書きます

```CSS:form.css
[type=text]{
	display: block;
	width:500px;
	margin-bottom: 10px;
}

```

```CSS:result.css
body{
    margin:0!important;
}

p{
    text-align: center;
}
```
bodyのmarginはユーザーエージェントによって指定されてるのでimportantで解除します
これは後にvwという画面の横幅を参照するcssの単位を使うのでそろ得たかったためこんなことをしました

```CSS:button.css
.btn-flat-border {
  display: inline-block;
  padding: 0.3em 1em;
  text-decoration: none;
  color: #67c5ff;
  border: solid 2px #67c5ff;
  border-radius: 3px;
  transition: .4s;
}

.btn-flat-border:hover {
  background: #67c5ff;
  color: white;
}
input.btn-flat-border{
	background: white;
}
```
URL入力を決定するボタンがデフォルトだと格好悪いので、お借りしたCSSにします　
お借りしたサイト
https://saruwakakun.com/html-css/reference/buttons
##step4 javascriptを書く
動画を埋め込むにはjavascriptが必要なので書いていきます

```javascript:result.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 get_text = document.location.search;
get_text = get_text.replace(/https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D/g,"");
get_text = get_text.substring(1, get_text.length);
let result = {};


for (var dat of get_text.split('\&')) {
	result[dat.replace(/=.*/, '')] = dat.replace(/.*=/, '');
}
var ytnum = 0;
for (var val of Object.values(result)) {
	if (!(val == "")) {
		ytnum++;
	}
}
var div = [];
var video = [];
for (var i = 0; i < ytnum; i++) {
	div[i] = document.createElement("div");
	video[i] = "video" + i;
	div[i].setAttribute("id", video[i]);
	var ele = document.getElementById("videos");
	ele.appendChild(div[i]);
}
function onYouTubeIframeAPIReady() {
	var ytPlayer = [];
	for (var i = 0; i < ytnum; i++){
		ytPlayer[i] = new YT.Player(
			'video'+i,
			{
				width: 500,
				height: 500,
				videoId: result['u'+ ( i + 1 )],
				events: {
					'onReady': onPlayerReady,
				}
			}
		);
		var target = document.getElementById("video"+i);
		switch(ytnum){
			case 1:
				target.style.cssText += "width : 100vw !important;height : calc(100vw*0.5625) !important;";
				break;
			case 2:
				target.style.cssText += "width : 50vw !important;height : calc(50vw*0.5625) !important;";
				break;
			case 3:
				target.style.cssText += "width : 33.3vw !important;height : calc(33.3vw*0.5625) !important;";
				break;
			case 4:
				target.style.cssText += "width : 25vw !important;height : calc(25vw*0.5625) !important;";
				break;
			case 5:
				target.style.cssText += "width : 20vw !important;height : calc(20vw*0.5625) !important;";
				break;
			
		}
		

	}
}

function onPlayerReady(event) {
	event.target.playVideo();
}
:
```

```javascript
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
```
ここでYouTube Player APIを読み込んでいます

```javascript
var get_text = document.location.search;
get_text = get_text.replace(/https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D/g,"");
get_text = get_text.substring(1, get_text.length);
let result = {};


for (var dat of get_text.split('\&')) {
	result[dat.replace(/=.*/, '')] = dat.replace(/.*=/, '');
}
var ytnum = 0;
for (var val of Object.values(result)) {
	if (!(val == "")) {
		ytnum++;
	}
}
```
ここではform.htmlで入力されたクエリパラメータを取得してresult配列に入れたあと、入力されたURLの数をytnumに入れています

```javascript
var div = [];
var video = [];
for (var i = 0; i < ytnum; i++) {
	div[i] = document.createElement("div");
	video[i] = "video" + i;
	div[i].setAttribute("id", video[i]);
	var ele = document.getElementById("videos");
	ele.appendChild(div[i]);
}
```
ここではjavascriptを使って動的にytnumの数だけタグを生成しています
理由はURLがいくつ入力されるかは入力されるまでわからないからです

```javascript
function onYouTubeIframeAPIReady() {
	var ytPlayer = [];
	for (var i = 0; i < ytnum; i++){
		ytPlayer[i] = new YT.Player(
			'video'+i,
			{
				width: 500,
				height: 500,
				videoId: result['u'+ ( i + 1 )],
				events: {
					'onReady': onPlayerReady,
				}
			}
		);
		var target = document.getElementById("video"+i);
		switch(ytnum){
			case 1:
				target.style.cssText += "width : 100vw !important;height : calc(100vw*0.5625) !important;";
				break;
			case 2:
				target.style.cssText += "width : 50vw !important;height : calc(50vw*0.5625) !important;";
				break;
			case 3:
				target.style.cssText += "width : 33.3vw !important;height : calc(33.3vw*0.5625) !important;";
				break;
			case 4:
				target.style.cssText += "width : 25vw !important;height : calc(25vw*0.5625) !important;";
				break;
			case 5:
				target.style.cssText += "width : 20vw !important;height : calc(20vw*0.5625) !important;";
				break;
			
		}
		

	}
}

function onPlayerReady(event) {
	event.target.playVideo();
}
```
ここではonYouTubeIframeAPIReady関数を使ってAPIがロードされたら、ytnumの数だけ生成されたタグに動画を埋め込んだあと、ytnumの数によってCSSを変更しています
また、デフォルトだと自動で動画は再生されないので、動画が埋め込まれると着火するonPlayerReady関数で動画を再生させています
以上で完成です
##実際に使ってみる
http://multitube.starfree.jp/
アップロードしたサイトです
無料ドメインでhttpなので「安全ではありません」と表示されていますが大丈夫です
まだ3つ4つ5つ同時に視聴するときのCSSが最適解ではないので気が向いたら更新します