html5+canvas+cssで動画再生周りを軽く作ってみた

#最初に
html5+canvas+cssで動画をいじれるページを作ろうとしていたのだけど、
ざっとネット見たら簡単なサンプルが少なかったのでメモを兼ねて。

引っ掛かった記事が引用元無しのパクりで腹立ったのでまともなのを残しとこう、が本音

#前提
chrome バージョン 56.0.2924.87 (64-bit)
IE11でも簡易確認済み
動画は適当にmp4使ってください
jQueryはとりあえず1.11.4を使用…しているけど、今回は未使用。

#最初の走り
javascriptの基礎あたりはさすがにわかってる前提で。
##canvas自体はこいつを写経
http://nigohiroki.hatenablog.com/entry/2013/01/04/025502

線の色とか太さ変えるくらいでさっさと次に

##動画との連携はこいつを写経
http://sterfield.co.jp/designer/video%E3%82%BF%E3%82%B0%E3%81%AE%E5%8B%95%E7%94%BB%E3%82%92canvas%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B/

ここまでやって、demo4の動作から一歩先に行く記事が見当たらなかったので、道を振り返りつつ。

#次の一歩
次に何をやるか考えるなら、それはvideoタグでのコントローラに搭載されているものの実装ですよね。さて、どんなコントローラがあったでしょう。

さっさと答えを書いてしまうと
・現在再生位置の時間と全再生時間の表示(「13:41/39:08」みたいなやつ）
・ミュート/音量調整
・全画面表示切替ボタン

全画面についてはめんどくさそうなので、とりあえずそれ以外で。
基本的にdemo4に追記する形で進めていきます。練習なのでスクリプトもhtmlに生で書いてますが、適当にjsファイル外出しでも何ら問題ないです。まじめに使うときはちゃんとカプセル化とかも考えましょう。

##リソース取得
###現在の再生時間と全再生時間を拾ってくる
demo4の挙動に

```html:hoge.html

if(video.paused){
		video.play()
	}else{
		video.pause();
	};
```

って書いてあったということは、videoのメソッドにいろいろ取れるのがあるんじゃないかと睨めれば、いろいろできることが見えてくるはず。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/video
ココが見つかった時点で勝ち確。第三部完（
https://zxcvbnmnbvcxz.com/html5-audio-mute-play-skip/
実例的な（音声ファイルの記事だけど、大体同じ事が出来ます）

早速それっぽいものを書いてみる。demo4の該当箇所だけ。

```html:hoge.html
（スクリプト部）
setInterval(function(){
	 var canvas = document.getElementById("c");
	 canvas.getContext("2d").drawImage(video, 0, 0, 480, 270);
	 var timeline = document.getElementById("t"); // この行と
	 timeline.textContent = video.currentTime + "/" + video.duration; // この行追加
 }, 1000/30);
（body部：ボタンの隣あたりに以下を追加）
<span id="t">（ここに時間が出るよ）</span>
```

どん！
0%0%0%

もとい、時間が秒単位で出てくると思います（例：2.236067/389.514889）。
大分小数点以下も出てくるのが嫌で成形したい人は適当にtoHms関数でも書きましょう。
時間をかけるのもアレなので、軽く検索して出てきたやつをちょっとだけアレンジ。
http://www.m-bsys.com/code/javascript-tohms

```html:hoge.html
（スクリプト部）
function toHms(t) {
	var hms = "";
	var h = t / 3600 | 0;
	var m = t % 3600 / 60 | 0;
	var s = parseInt(t % 60);
	var x = parseInt((t % 60 - parseInt(t % 60))*100);

	hms = h + ":" + padZero(m) + ":" + padZero(s) + ";" + padZero(x);
	return hms;

	function padZero(v) {
		if (v < 10) {
			return "0" + v;
		} else {
			return v;
		}
	}
}
```
これをさっきの出力に噛ませれば「0:08:09;06/1:34:13;98」とかみたいな感じに出ると思います。
適当に流したのでもっとよさそうなの有れば教えてください。

###ボリューム
もう全く同じ要領で行けますね。

```html:hoge.html
（スクリプト部）
setInterval(function(){
	 var canvas = document.getElementById("c");
	 canvas.getContext("2d").drawImage(video, 0, 0, 480, 270);
	 var timeline = document.getElementById("t");
	 timeline.textContent = toHms(video.currentTime) + "/" + toHms(video.duration);
	 var volume = document.getElementById("s"); // この行と
	 volume.textContent = video.volume ; // この行追加
 }, 1000/30);
（body部：ボタンの隣あたりに以下を追加）
<span id="s">（ここに音量が出るよ）</span>
```

音量調整のシークバーを実装するのは面倒なので、後述の方法を使ってボタンで適当に固定値増減するのを作ったりしましょう。
僕は面倒くさがりなので、video側のdisplay:none;を外して、そっちの音量スライダーを動かして確認することで満足しました。手抜き！

###ミュート切り替え
こいつは音量とは別に作れるので。

```html:hoge.html
（スクリプト部）
function changeMute(){
var video = document.getElementById("v");
 
if(video.muted){
		video.muted = false;
	}else{
		video.muted = true;
	}
}
（body部：ボタン追加）
<input type="button" value="ミュート切替" onClick="changeMute()">
```

ここまで来れば特に難しいということはない気がする。

###コマ送り、コマ戻し
ときどき見かける機能なので。戻しだけ記述。

```html:hoge.html
（スクリプト部）
function reverseFlame(){
var video = document.getElementById("v");

if(!video.paused){
		video.pause();
	}

	video.currentTime -= 1/30; // 30F/1sec前提
}
（body部：ボタン追加）
<input type="button" value="１コマ戻す" onClick="reverseFlame()">
```

はい、さっきまでの応用で行けました。コマ送りは+-逆にするだけなので割愛。
この作りの延長線で音量の固定値増減もいけるので、試したい人はその辺くらいは応用問題でいいかと。

##今後の課題、というか次にやりたいこと
音量スライダーバーは次あたりにjQuery使って実装してみようかと。
後はプログレスバーだけど、これも大体同じ感じになるのかしら…？

#最後に
くれぐれも書きますが入門用とか動作チェック用にいろいろ端追っているので、まじめにやるならjavascript部分の外出しとかカプセル化とか考えてね。