Youtube動画を、モーダルを開くと同時に自動再生させる方法[Youtube IFrame Player API, JavaScript]

Youtube動画を、モーダルを開くと同時に自動再生させる方法[Youtube Iframe API, JavaScript]
YouTube動画は、デフォルトでもWebサイトに埋め込んで再生させること自体はできます。
ただし実際のWeb制作の案件で、
特定のダイアログ(≒モーダル)を開いたら、お店(または企業)の公式YouTube動画を自動再生するようにしてほしい
という様なオーダーを受けたら、どうすれば良いでしょうか。

今回は、そんな場合に対応する方法について、記事を書いていきます。

YouTube動画にJavaScriptからアクセスできる「IFrame Player API」

さて早速、どうすれば実現できるの、と言う話ですが実は、
冒頭の様なオーダーに対応できる様に、YouTubeが公式APIを公開してくれています。

名前は「IFrame Player API」というものになります。

こちらは文字通り、IFrame読み込みしたYouTube動画を、JavaScriptで制御する事が可能になるAPIです。

これを使うと、冒頭に書いたような「特定のダイアログ(≒モーダル)を開いたら、YouTube動画を自動再生する」といった事が比較的簡単に実現できるわけですね。

さてそれでは早速その使い方について、書いていきたいと思います。

JavaScriptのコードなど

こちらが 「IFrame Player API」 を使用するための、
JavaScript側のコード例になります。[1]〜[6]のセクションに分けてコメントを記載してあります。

// [1]. Youtube IFrame Player APIの読込_ページ内のscriptタグの前に動的に読込ませる仕様
let makeScriptTag = document.createElement('script');
makeScriptTag.src = "https://www.youtube.com/iframe_api";
let asyncScriptTag = document.getElementsByTagName('script')[0];
asyncScriptTag.parentNode.insertBefore(makeScriptTag, asyncScriptTag);

// [2]. Youtube IFrame Player APIが実行してくれる関数の定義_ここで動画に関する情報を設定する
let targetPlayer;
function onYouTubeIframeAPIReady() {
  targetPlayer = new YT.Player('targetPlayer', {
    height: '380px',
    width: '676px',
    videoId: '***********', // 再生したい動画のID11桁
    events: {
      'onReady': onPlayerReady,
      // 'onStateChange': onPlayerStateChange
    }
  });
}

// [3]. 再生準備ができたら再生ボタンを活性化する
function onPlayerReady(event) {
  movieTrigger.classList.add('is-ready');
}

// [4]. ページ内の各要素をquerySelectorで指定して変数に格納
const movieTrigger = document.querySelector('.movie-trigger');
const movieDialog = document.querySelector('.movie-dialog');
const movieDialogBackground = document.querySelector('.movie-dialog-background');
const movieClose = document.querySelector('.movie-dialog-close');

// [5]. モーダルを開くボタンを押した時の挙動を定義
movieTrigger.addEventListener('click', (e) => {
  movieDialog.classList.add('is-show');
  movieDialogBackground.classList.add('is-show');
  targetPlayer.mute();
  targetPlayer.playVideo();
});

// [6]. モーダルを閉じる挙動を定義
movieDialogBackground.addEventListener('click', (e) => {
  movieDialog.classList.remove('is-show');
  movieDialogBackground.classList.remove('is-show');
  targetPlayer.stopVideo();
});

movieClose.addEventListener('click', (e) => {
  movieDialog.classList.remove('is-show');
  movieDialogBackground.classList.remove('is-show');
  targetPlayer.stopVideo();
});

何が書いてあるかの解説など

少し長いコードですが、内容はコメントアウトに記載してある通りとなります。

[1]. の部分(Youtube IFrame Player APIの読み込み)

[1]. の部分では、YouTubeの「IFrame Player API」を読み込んでいます。
一度 document.createElement('script') として
scriptタグを生成、そこにsrc属性を付与してあげ、それを
document上のscriptタグの一番最初に insertBefore() (ざっくり言うと差し込んでいる)、という記述です。

この記述で、YouTubeの「IFrame Player API」の読み込みが完了しています。

[2]. の部分(関数の定義。ここで動画に関する情報を設定する)

続く
[2]. の部分では、YouTubeの「IFrame Player API」が実行してくれる関数の定義です。
onYouTubeIframeAPIReady() 関数に、
「どの要素内にIframeを設置するか」
「どれくらいのサイズで」
「どの動画IDのムービーを再生させるか」
「再生時に取得させるイベントは何か」
といった設定を渡してあげている記述です。
変数 let targetPlayer を定義しておき、ここに
new YT.Player として、動画の設定を渡します。
new YT.Player の第一引数には
Iframeを設置する要素をidで指定。
new YT.Player の第二引数に、各種設定を記述する形となります。
設定の
height, width は文字通り縦横のサイズをpx値で指定。
videoId には再生したいYouTube動画のIDを指定。
(これは、再生したい動画を開き、ブラウザのURL欄にあるURL末尾にある ?v= 以降の文字列になります)

events には、「再生時に取得させるイベントは何か」の部分を定義します。
特段使わない場合は指定しなくても良いです。この例では、
‘onReady’ (再生準備が整った時)
を指定してあります。コメントアウトしてある
‘onStateChange’ は、「何か状態が変更された時」になります。
何らかの操作が行われたタイミングで何か処理を実行したい場合などに使えます。

[3]. の部分(再生準備ができたら再生ボタンを活性化)

[3]. では、上の[2]. で指定した ‘onReady’ (再生準備が整った時)イベントが発生したタイミングで実行する処理を書いています。
このサンプルでは、
再生準備が整ったら
特定のclassを再生ボタンに付与して
再生ボタンを押せる状態にする
ということを
movieTrigger.classList.add(‘is-ready’); として記述しています。
もちろん、あらかじめcss側では、
再生ボタンに pointer-events: none; を設定しておき押せない状態にしておき、
‘onReady’ (再生準備が整った時)イベントが発生したタイミングで、
is-ready というclassを渡してあげ、(この is-ready というclassには pointer-events: initial; を指定しておく)
再生ボタンを押せるようにしているということです。

[4]. の部分(ページ内の各要素をquerySelectorで指定)

続く [4]. ですが、ここは至ってシンプルで、
html上の必要な要素を quelySelector で取得、変数に格納しているという部分になります。
上から
・再生ボタン
・開くダイアログ本体
・開くダイアログ背景
・開くダイアログ内の閉じるボタン
になります。ここは何も難しいことはなく、
対応するclass名を持つ要素をあらかじめhtml内に置いておけば取得できる部分になります。

[5]. の部分([モーダルを開く]ボタンを押した時の挙動)

[5]. が、再生ボタンが押された時に実際に起きる処理を書いている部分になります。
上の [4]. で定義した再生ボタンである movieTrigger に対して、
それがクリックされた時(クリックイベントが発生した時)の挙動を書いている部分です。

addEventListener の第一引数にはイベント名を指定(この場合は click イベントを取りたいので click と指定)、
addEventListener の第二引数に、実行する関数を記載します。(この例では () => {} の形でアロー関数として実行する内容を定義しています)

[4]. で定義した
・開くダイアログ本体である movieDialog と
・開くダイアログ背景である movieDialogBackground に
それぞれ is-show というclassを渡してあげています。
もちろんここは、
・開くダイアログ本体
・開くダイアログ背景 について、
最初は display: none をcssで定義しておき、
is-show というclassが渡った時、display: block にしてあげる、と言う設定をあらかじめcssに用意しておくという事です。

最重要と言っても過言ではない「mute()」

とても重要な記述が、その次の行にある
targetPlayer.mute()
targetPlayer.playVideo()
になります。

targetPlayer.mute() でまず、対象の動画の音声をミュート。
その上で
targetPlayer.playVideo() を使って再生しているわけですが、
これがとても重要な部分です。

この
mute() は絶対に書き忘れてはならない記述です。
これがないと、「音声付きでいきなり再生される」ことになりますので、
想像するとそれがよろしくない事は明白ですよね。
電車の中で、爆音で動画がいきなり再生されるようなケースを考えれば、この1行が必須な事は明白だと思います。

くれぐれも、この mute() は必須で記述するのを忘れないでください。
(※targetPlayer と言う命名は自由に設定する事が可能です。)

[6]. の部分(モーダルを閉じる挙動)

[6]. は、
「モーダルの背景をクリックした時」
「モーダル内の閉じるボタンをクリックした時」
「モーダルを閉じて、動画の再生も止める」
という部分の記述になります。

やっていることは [5]. の開く時のクリックイベントと同じような内容ですので、説明は省きます。
重要な点としては
classList.add を classList. remove にしているのと、
動画の再生を止めるために
targetPlayer.stopVideo(); を使用している点です。

以上の [1] 〜 [6] までで、

特定のダイアログ(≒モーダル)を開いたら、YouTube動画を自動再生する
と言う事が実現できるわけです。

最低限必要なhtml

最低限必要なhtmlは次です。たったこれだけです。
(3行目の movie-container すら、場合によっては要らないかもしれません)

<div class="movie-dialog">
  <a class="movie-dialog-close">とじる</a>
  <div class="movie-container">
    <div id="targetPlayer" class="movie-iframe-container"></div>
  </div>
</div>
<div class="movie-dialog-background"></div>

<a class="movie-trigger">再生する</a>

最低限必要なcss

最低限必要なcssをあげるとすれば、次のような形でしょうか。
これはもう、案件によって要件も違うと思いますので、本当にお好みで自由にスタイリングするのが良いと思います。

.movie-dialog {
  background: #fff;
  border-radius: 0.5rem;
  display: none;
  height: 500px;
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 800px;
  z-index: 50;
}
@media screen and (max-width: 500px) {
  .movie-dialog {
    width: calc(100% - 2rem);
  }
}
.movie-dialog.is-show {
  align-items: center;
  display: flex;
  justify-content: center;
}
.movie-dialog-close {
  cursor: pointer;
  position: absolute;
  right: 1rem;
  top: 0.75rem;
}
.movie-dialog-background {
  background: rgba(0, 0, 0, 0.5);
  display: none;
  height: 100vh;
  left: 0;
  position: fixed;
  top: 0;
  width: 100vw;
  z-index: 10;
}
.movie-dialog-background.is-show {
  display: block;
}
.movie-dialog iframe {
  height: 100%;
  width: 100%;
}
.movie-trigger {
  color: #585858;
  pointer-events: none;
}
.movie-trigger.is-ready {
  cursor: pointer;
  pointer-events: initial;
}
.movie-container {
  height: 380px;
  position: relative;
  width: 676px;
}
@media screen and (max-width: 500px) {
  .movie-container {
    aspect-ratio: 16/9;
    height: auto;
    width: calc(100% - 2rem);
  }
}
.movie-iframe-container {
  height: 380px;
  position: relative;
  width: 676px;
}
@media screen and (max-width: 500px) {
  .movie-iframe-container {
    height: auto;
    width: calc(100% - 2rem);
  }
}
.movie-iframe-container iframe {
  height: 100%;
  position: absolute;
  width: 100%;
}
.movie-trigger {
  text-decoration: none;
}

YouTube公式の解説ページ

今回ご紹介した
「IFrame Player API」
の、YouTube公式の解説ページは次のURLになります。
https://developers.google.com/youtube/iframe_api_reference?hl=ja

↑やはり、公式解説が一番正確で、一番わかりやすいと思います。

この記事のまとめ

今回は、Web制作をしている際に
特定のダイアログ(≒モーダル)を開いたら、お店(または企業)の公式YouTube動画を自動再生するようにしてほしい
という様なオーダーを受けた場合に対応できるようにする方法について記事を書いてみました。
具体的には
「IFrame Player API」
を使用する方法になります。

この
「IFrame Player API」、今回の例で使用した
‘onReady’ イベント以外にも幾つかのイベントを取得する事ができますので、
実際にいろいろ試してみると、案件によっては役立つことかと思います。

この記事が皆さんのより良いWeb制作体験につながれば、嬉しく思います。

※この記事は内容の品質向上を目的に、随時更新を行う場合があります。

この記事をシェアする: