YouTube 埋め込み API の薄いラッパークラスを作成してみた
iframe 組み込みの YouTube Player API リファレンス | YouTube IFrame Player API | Google Developers を参考にすれば JavaScript を用いた YouTube の動画埋め込みは容易にできます。
しかし、JS ファイルを webpack 等でバンドルしていのであれば YouTube 埋め込み動画の処理もまとめてしまいたいと思ったり、動的に YouTube の動画を埋め込みたい場合はちょっと扱いづらさを感じるので、もう少し取り回しがし易いように wrapper クラスを作成してみました。
以下のソースは煮るなり焼くなり好きにしてください。
Class 構文
class YouTubePlayer {
constructor(dom, option) {
this.dom = dom;
this.option = option;
this.option.events = this.option.events || {};
this._player = null;
this.events = this.option.events;
if (!window.onYouTubeIframeAPIReady || !window.YT?.Player) {
const script = document.createElement("script");
script.src = "https://www.youtube.com/iframe_api";
document.body.appendChild(script);
window.onYouTubeIframeAPIReady = () => this._player = this.apply();
} else {
this._player = this.apply();
}
}
get player() { return this._player }
apply = () => new window.YT.Player(this.dom, this.option);
onReady = (callback) => this.option.events.onReady = callback;
onStateChange = (callback) => this.option.events.onStateChange = callback;
onPlaybackQualityChange = (callback) => this.option.events.onPlaybackQualityChange = callback;
onPlaybackRateChange = (callback) => this.option.events.onPlaybackRateChange = callback;
onError = (callback) => this.option.events.onError = callback;
onApiChange = (callback) => this.option.events.onApiChange = callback;
}
Prototype 構文
一応、~~忌々しき~~ IE11 等で Babel 噛まさなくても良いように、勉強を兼ねて Prototype 構文でも書いてみました。
class 構文と微妙にアクセスできるメンバ変数とか違うと思います。
var YouTubePlayer = function (dom, option) {
if (!(this instanceof YouTubePlayer)) {
return new YouTubePlayer(dom, option);
}
var self = this;
this.dom = dom;
this.option = option;
this.option.events = this.option.events || {};
this.player = null;
var apply = function () { return new window.YT.Player(self.dom, self.option); };
if (!window.onYouTubeIframeAPIReady || !window.YT || !window.YT.Player) {
var script = document.createElement("script");
script.src = "https://www.youtube.com/iframe_api";
document.body.appendChild(script);
window.onYouTubeIframeAPIReady = function () { self.player = apply(); };
} else {
this.player = apply();
}
};
YouTubePlayer.prototype = {
onReady: function (callback) { this.option.events.onReady = callback; },
onStateChange: function (callback) { this.option.events.onStateChange = callback; },
onPlaybackQualityChange: function (callback) { this.option.events.onPlaybackQualityChange = callback; },
onPlaybackRateChange: function (callback) { this.option.events.onPlaybackRateChange = callback; },
onError: function (callback) { this.option.events.onError = callback; },
onApiChange: function (callback) { this.option.events.onApiChange = callback; }
};
使い方
上記の script を読み込ませた上で、以下のような記述ができます。
以下のような HTML があったとして。
<div id="app"></div>
<button id="play">再生する</button>
以下のような script を記載できるようになります。
今回独自で作成した YouTubePlayer
クラスのコンストラクタ引数は YouTube が提供している YT.Player
クラスのコンストラクタ引数と同じものを渡せば動作します。
const player = new YouTubePlayer('app', { videoId: 'z13S9g_RIVk' });
player.onReady((e) => document.getElementById('play')
.addEventListener('click', () => e.target.playVideo()));
上記の onReady
の記載の通り YT.Player
のオプション引数の events
で全てイベント系を予め定義しなくとも、以下のイベント系のメソッドだけ生やしているので、なにか制御したいものがあれば、よしなに利用できるようにしてます。
-
onReady
-
onStateChange
-
onPlaybackQualityChange
-
onPlaybackRateChange
-
onError
-
onApiChange
また player
メンバ変数を生やし YT.Player
のオブジェクトが取得できるので、もっと細かな制御をしたい場合は player
変数を取得してもらえればと思います。