HTML5 の Video タグを使って動画のコマ送り、スロー再生ができるプレイヤーを作る

# やること

HTML5 の video タグが便利すぎて、痒いところに手が届かない無料の mp4 プレイヤーをダウンロードするくらいなら、自分で作ったほうが早いよね、みたいな。でも、すぐ使い方を忘れるので忘備録です。

# 準備

- windows/mac + chrome / firefox, mac + safari, android + chrome はいけるようです。windows 10 + edge でもいけました。
- ローカルにある mp4 ファイルを開く前提です。オンライン化するには https 化が必要です (多分)

OS/ブラウザの対応状況は下記を参考に:
- https://developer.mozilla.org/ja/docs/Web/HTML/Element/video

# コード

再生、停止、再生速度の変更、コマ送り、早送り、音量変更と、これでだいたいのことはできます。サンプルのコードなので、エラー処理は甘いです。init_video() は mp4 の読み込みタイミングによってはエラーが出たりします。

下記コードを動かすためには、適当な mp4 ファイルを source で指定してください。

video タグの controls を消すと、動画上でシークするバーみたいなものが出なくなります。

```index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

</head>
<body>

<table>
<tr>
<td>
    <video id="video" height="480" controls>
        <source src="sample.mp4">
    </video>
    </td>
<td>
    <div>
    <input type="button" value="再生" onClick="playVideo()">
    <input type="button" value="一時停止" onClick="pauseVideo()"> 
    <br>

    <input type="button" value="1秒前" onClick="seekDown()">
    <input type="button" value="1秒後" onClick="seekUp()">
    <br>

    <input type="button" value="-0.1倍" onClick="fast()">
    <input type="button" value="+0.1倍" onClick="slow()">
    <input type="button" value="元の速度" onClick="setSpeed(1)">
    <br>

    <input type="button" value="音量UP" onClick="changeVolume(0.1)">
    <input type="button" value="音量DOWN" onClick="changeVolume(-0.1)">
    <input type="button" value="元の音量" onClick="setVolume(1)">
    <br>

    <input type="button" value="先頭へ" onClick="seekToTop()">
    <input type="button" value="最後へ" onClick="seekToLast()">
    <br>
    現在（秒）：<span id="position">0</span><br>
    全体（秒）：<span id="length"></span><br>
    再生速度  ：<span id="speed">1.0</span><br>
    音量      ：<span id="volume">1.0</span><br>
    <span id="message"></span>
</div>
</td>
</tr>
</table>

<script>
    var v;
    
    function init_video(){
        v = document.getElementById("video");
        
        v.onloadeddata = function()
        {
            document.getElementById("length").innerHTML = v.duration;
        }
        
        v.addEventListener("timeupdate", function(){
            document.getElementById("position").innerHTML = v.currentTime;
            document.getElementById("speed").innerHTML = v.playbackRate.toFixed(1);
        }, false);
        
        v.addEventListener("ended", function(){
            document.getElementById("message").innerHTML = "finished";
        }, false);
        
        v.addEventListener("pause", function(){
            document.getElementById("message").innerHTML = "paused";
        },false);
    }
    
    function playVideo() {
        document.getElementById("message").innerHTML = "playing..";
        v.play();
    
    }
    
    function pauseVideo() {
        v.pause();
    }
    
    function changeVolume( val ) {
        v.volume += val;
        document.getElementById("volume").innerHTML = v.volume.toFixed(1);
    }
    
    function setVolume( val ){
        v.volume = val;
    }
    
    function seekUp() {
        v.currentTime += 1;
    }
    
    function seekDown() {
        v.currentTime -= 1;
    }
    
    function seekToTop(){
        v.currentTime = 0;
    }
    
    function seekToLast(){
        v.currentTime = v.duration;
    }
    
    function slow() {
        v.playbackRate += 0.1;
    }
    
    function setSpeed( speed ) {
        if ( speed < 0.1 ){
            speed = 0.1;
        }
        v.playbackRate = speed;
    }
    
    function fast() {
        if ( v.playbackRate > 0.1){
            v.playbackRate -= 0.1;
        }
    }
    init_video();
</script>
</body>
</html>
```

# 参考

- https://developer.mozilla.org/ja/docs/Web/HTML/Element/video 
- https://itsakura.com/html5-video
- https://webliker.info/52510/
- http://www.htmq.com/html5/video.shtml