いまさらHTML5 （簡易プレイヤー編）

## はじめに

mp3やmp4のプレイヤーは、世間的には「Windows Media Player」が一番利用されているのではないかと思いますが
HTML5をやってみて、ブラウザでも再生できるのではと思い、AUDIOタグとVIDEOタグを利用して、プレイヤーを作ってみます。

## 簡易プレイヤー

以下を満たすものを作成します。

* 1ファイルで作成（JQueryとか使わない）
* ファイル追加はドラッグ・アンド・ドロップ
* 連続再生（ファイル順に再生）

JQueryが使えないので`addEventListener`でイベント設定を行います。
連続再生は、AUDIOタグやVIDEOタグの`ended`イベントを受信したら次を再生する仕組みにしています。
（シークしまくっていたら、`ended`イベントが来ない事があったので、次へボタンを作成しました。）

```html:simpleplayer.html
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>簡易プレイヤー</title>
    <script type="text/javascript">
        // VIDEOタグ
        var video = null;
        // AUDIOタグ
        var audio = null;
        // ファイル一覧
        var list = [];
        // 初期処理
        function init() {
            // ファイルドロップイベント設定
            document.getElementById("drop").addEventListener("dragover", eventStop, false);
            document.getElementById("drop").addEventListener("drop", filedrop, false);
            // VIDEOタグ取得
            video = document.getElementById("video");
            // 終了イベント取得設定
            video.addEventListener("ended", playerEvent, false);
            // VIDEO非表示
            video.style.display = "none";
            // AUDIOタグ取得
            audio = document.getElementById("audio");
            // 終了イベント取得設定
            audio.addEventListener("ended", playerEvent, false);
            // AUDIO非表示
            audio.style.display = "none";
            // 次へボタン押下イベント設定
            document.getElementById("next").addEventListener("click", next, false);
            // 次へボタン非表示
            document.getElementById("next").style.display = "none";
        }
        // ファイルがドラッグされた場合
        function eventStop(event) {
            // イベントキャンセル
            event.stopPropagation();
            event.preventDefault();
            // 操作をリンクに変更
            event.dataTransfer.dropEffect = "link";
        }
        // ファイルがドロップされた場合
        function filedrop(event) {
            try {
                // イベントキャンセル
                event.stopPropagation();
                event.preventDefault();
                // ファイル存在チェック
                if (event.dataTransfer.files) {
                    var old = list.length;
                    // ファイル一覧取得
                    var files = event.dataTransfer.files;
                    // ファイル数分ループ
                    for (var i = 0; i < files.length; i++) {
                        // ファイル取得
                        var file = files[i];
                        // 再生可能ファイルであるか判定
                        if (video.canPlayType(file.type) || audio.canPlayType(file.type)) {
                            // ファイル情報生成
                            var item = {
                                name: file.name,
                                type: file.type,
                                url: URL.createObjectURL(file)
                            };
                            // ファイル追加
                            list.push(item);
                        }
                    }
                    // 表示
                    view();
                    // 最初であるか判定
                    if (old == 0 && list.length > 0) {
                        // 次へボタン表示
                        document.getElementById("next").style.display = "block";
                        // 次を再生（最初）
                        next();
                    }
                }
            } catch (e) {
                // エラーの場合
                alert(e.message);
            }
        }
        // 次を再生
        function next() {
            // ファイル数チェック
            if (list.length > 0) {
                // 最初のファイルを設定
                var item = list[0];
                // ファイル数分ループ
                for (var i = 0; i < list.length; i++) {
                    // VIDEOタグかAUDIOタグと一致するか判定
                    if (video.src === list[i].url || audio.src === list[i].url) {
                        // 最後のファイルか判定
                        if (i != list.length - 1) {
                            // 次のファイルを設定
                            item = list[i + 1];
                            break;
                        }
                    }
                }
                // AUDIO停止
                audio.pause();
                // VIDEO停止
                video.pause();
                // タイプ判断
                if (item.type.indexOf("audio/") == 0) {
                    // AUDIOなので、VIDEO初期化
                    video.src = "";
                    video.style.display = "none";
                    // AUDIO表示
                    audio.style.display = "block";
                    // 前回とURLが異なるか判定
                    if (audio.src != item.url) {
                        // URL更新
                        audio.src = item.url;
                    }
                    // AUDIO再生
                    audio.play();
                } else if (item.type.indexOf("video/") == 0) {
                    // VIDEOなので、AUDIO初期化
                    audio.src = "";
                    audio.style.display = "none";
                    // VIDEO表示
                    video.style.display = "block";
                    // 前回とURLが異なるか判定
                    if (video.src != item.url) {
                        // URL更新
                        video.src = item.url;
                    }
                    // VIDEO再生
                    video.play();
                }
                // ファイル名表示
                document.getElementById("playfilename").textContent = item.name;
            }
        }
        // イベント取得
        function playerEvent(event) {
            // イベントタイプ判定
            if (event.type == "ended") {
                // 終了なので、次へ
                next();
            }
        }
        // 表示
        function view() {
            // 表示されているリスト取得
            var nodes = document.getElementById("playlist").childNodes;
            // 全部削除
            while (nodes.length > 0) {
                document.getElementById("playlist").removeChild(nodes[0]);
            }
            // リスト数分追加
            for (var i = 0; i < list.length; i++) {
                var div = document.createElement("div");
                div.textContent = list[i].name;
                document.getElementById("playlist").appendChild(div);
            }
            // 表示幅調整
            document.getElementById("playlist").style.width = "100%";
        }
        // ロードイベント登録
        window.addEventListener("load", init, false);
    </script>
</head>
<body>
    <div id="drop" style="position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; overflow: auto;">
        <table>
            <tbody>
                <!-- ファイル名＆次へ部分 -->
                <tr>
                    <td colspan="2"><div id="playfilename"></div></td>
                    <td style="width: 50px"><button id="next" style="width: 50px">次へ</button></td>
                </tr>
                <!-- プレイヤー部分 -->
                <tr>
                    <td colspan="3" style="width: 400px; height: 40px;">
                        <div style="resize: both; overflow: auto; width: 100%;">
                            <video id="video" controls style="width: 99%; height: 99%;"></video>
                            <audio id="audio" controls style="width: 99%; height: 40px"></audio>
                        </div>
                    </td>
                </tr>
                <!-- ドロップ＆一覧部分 -->
                <tr>
                    <td style="white-space: nowrap;" colspan="3">
                        <div id="playlist" style="width: 100px; height: 100px; overflow: auto;"></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>
```

## 感想

思ったより簡単に出来ました。
デザインセンスが無いのはお察し下さい。
一度、ブラウザを閉じてしまうと全部初期化してしまいます。