みかづきブログ その3

3ヶ月つづけてみました。

続・YouTubeの埋め込みプレーヤーを管理するクラスをつくる

以前つくったクラス を改修しました。

kimizuka.hatenablog.com


変更点

  • currentTImeを取得できるように変更しました。
(function(win) {
    
    "use strict";
    
    win.App = {};

})(this);

(function(win, doc, ns) {

    "use strict";

    function EventDispatcher() {
        this._events = {};
    }

    EventDispatcher.prototype.hasEventListener = function(eventName) {
        return !!this._events[eventName];
    };

    EventDispatcher.prototype.addEventListener = function(eventName, callback) {
        if (this.hasEventListener(eventName)) {
            var events = this._events[eventName],
                length = events.length,
                i = 0;
    
            for (; i < length; i++) {
                if (events[i] === callback) {
                    return;
                }
            }

            events.push(callback);
        } else {
            this._events[eventName] = [callback];
        }
    };

    EventDispatcher.prototype.removeEventListener = function(eventName, callback) {
        if (!this.hasEventListener(eventName)) {
            return;
        } else {
            var events = this._events[eventName],
                i = events.length,
                index;
    
            while (i--) {
                if (events[i] === callback) {
                    index = i;
                }
            }
    
            events.splice(index, 1);
        }
    };

    EventDispatcher.prototype.fireEvent = function(eventName, opt_this, opt_arg) {
        if (!this.hasEventListener(eventName)) {
            return;
        } else {
            var events     = this._events[eventName],
                copyEvents = _copyArray(events),
                arg        = _copyArray(arguments),
                length     = events.length,
                i = 0;
    
            // eventNameとopt_thisを削除
            arg.splice(0, 2);
    
            for (; i < length; i++) {
                copyEvents[i].apply(opt_this || this, arg);
            }
        }
    
        function _copyArray(array) {
            var newArray = [],
                i = 0;
    
            try {
                newArray = [].slice.call(array);
            } catch(e) {
                for (; i < array.length; i++) {
                    newArray.push(array[i]);
                }
            }
    
            return newArray;
        }
    };

    function YTPlayer() {
        var _this = this,
            _player = null,
            isAutoStart = false;;

        EventDispatcher.call(this);

        _init();

        function _init() {
            var tag            = doc.createElement("script"),
                firstScriptTag = doc.getElementsByTagName("script")[0];

            tag.src = "https://www.youtube.com/iframe_api";
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

            function onYouTubeIframeAPIReady() {
                _this.fireEvent("YOUTUBE_READY");
            }

            // export
            win.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;
        }

        function _onPlayerReady(evt) { // 動画再生準備完了時イベント
            var player = this.target;

            if (isAutoStart) {
                player.playVideo(); // 動画再生
            }
        }

        function _onPlayerStateChange(evt) { // 動画再生状態変更時イベント
            switch (this.data) {
                case -1: // 未開始
                    _this.fireEvent("UNSTARTED", this.target, evt);
                    break;
                case 0: // 再生終了時
                    _this.fireEvent("ENDED_VIDEO", this.target, evt);
                    break;
                case 1: // 再生開始時
                    _this.fireEvent("PLAYING_VIDEO", this.target, evt);
                    break;
                case 2: // 一時停止時
                    _this.fireEvent("PAUSED_VIDEO", this.target, evt);
                    break;
                case 3: // バッファリング
                    _this.fireEvent("BUFFERING_VIDEO", this.target, evt);
                    break;
//                case 5: // 頭出し済み
//                    break;
            }
        }

        /**
         * Playerを生成します
         * @param  {string}  id      // Player に置換する DOM の id属性(必須)
         * @param  {string}  videoId // YouTube の video ID(必須)
         * @param  {object}  opt_obj // オプション用のオブジェクト
         *         {number}  width       // プレイヤーの幅(省略時は640)
         *         {number}  height      // プレイヤーの高さ(省略時は480)
         *         {boolean} isAutoStart // 自動再生するか否か(省略時はfalse)
         * @return {object} // play, stopを持ったコントローラーオブジェクト
         */
        function build(id, videoId, opt_obj) {
            _player = new YT.Player(id, {
                    width   : (opt_obj && opt_obj.width)  || 640, // 動画幅
                    height  : (opt_obj && opt_obj.height) || 480, // 動画高さ
                    videoId : videoId,       // 動画ID
                    events  : {
                        onReady : function(player) {
                            _onPlayerReady.call(player, id);
                        },
                        onStateChange : function(player) {
                            _onPlayerStateChange.call(player, id);
                        }
                    },
                    playerVars: {
                        rel      : 0, // 関連動画
                        showinfo : 0, // 動画情報
                        controls : 1, // コントローラー
                        wmode    : "transparent" // z-indexを有効にする
                    }
                });

            isAutoStart = (opt_obj && opt_obj.isAutoStart) || false;

            return {
                play: play,
                stop: stop,
                getCurrentTime: getCurrentTime // 追加
            };
        }
 
        function play() {
            if (_player.playVideo) {
                _player.playVideo();
            } else {
                isAutoStart = true;
            }
        }

        function stop() {
            if (_player.stopVideo) {
                _player.stopVideo();
            }
        }

        function getCurrentTime() {
            if (_player.getCurrentTime) {
                return _player.getCurrentTime();
            }
        }

        this.build = build;
    }

    YTPlayer.originalConstructor   = YTPlayer.prototype.constructor;
    YTPlayer.prototype             = new EventDispatcher();
    YTPlayer.prototype.constructor = YTPlayer.originalConstructor;

    ns.YTPlayer = {
        getInstance : function() {
            if (!YTPlayer.instance) {
                YTPlayer.instance = new YTPlayer();
            }

            return YTPlayer.instance;
        }
    };

})(this, document, App);

つかいかた

(function(win, doc, ns) {
    
    "use strict";
    
    var youTube = ns.YTPlayer.getInstance(),
        player;

    youTube.addEventListener("YOUTUBE_READY", function() {
        player = youTube.build("player", "1g0ebPju_eE");
    });

    youTube.addEventListener("PLAYING_VIDEO", function(evt) {
        setTimeout(function() {
            console.log(player.getCurrentTime());
        }, 1000);
    });
    
})(this, document, App);

DEMO



今回は以上です。