Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

いまさらHTML5 (簡易プレイヤー編)

More than 5 years have passed since last update.

はじめに

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

簡易プレイヤー

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

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

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

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>

感想

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

tnakagawa
最近は、暗号ばっかやっている気がする。 数学得意だと思ってたけど、全然ダメダメだった。 もっと勉強しなければ・・・
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away