Pulog

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 変数を取得してもらえればと思います。