YouTubeの動画を背景に敷く(iOS対応、自動再生・ループ)

こんにちはナカムラです。
今回はYoutubeの動画を使って、背景に動画を敷いてみたいと思います。
実装する機能としては以下の2点になります。

  • 自動再生
  • ループ

レスポンシブを想定して、スマホにも対応するように作ります。
その場合は、YouTubeの「埋め込み」で取得できるコードではなく、APIを使って生成する必要があります。

※本記事は、APIの基本的な使い方を理解していることを前提として書いています。
APIの使い方については以前書いた記事をご覧ください。 tech.arms-soft.co.jp

YouTubeを背景に敷く上での注意点

下に記載しているDEMOを見るとわかりますが、最初に動画のタイトルなど、動画の情報が表示されます。これを消すことは仕様上できないので、オープニングアニメーションを用意し、動画の情報が消えるタイミングに合わせて表示を切り替える必要があるかと思います。(DEMOは動画の再生のみ実装しています) ユーザーの待ち時間が長くなってしまうので、ローディングのような単調なものではなく、飽きさせないようなアニメーションにしないと離脱されてしまうでしょう。

というわけで、YouTubeを背景動画にするのはおすすめできないです。
そもそも動画素材のためのサービスではないので、使う側の理解が必要かなと思います。

とはいえ、どうしても使わないといけない時もあるかもしれないので、
勉強がてらまとめていきたいと思います。

なぜAPIが必要なのか、iOS対応のポイント

APIのリファレンスで説明されていますが、iOSのSafariでは自動再生のパラメータが機能しません。
この問題を解決するために、パラメータで指定するのではなく、
プレイヤーの準備が整ったタイミングでmute()とplayVideo()を実行する必要があります。

DEMO

See the Pen YouTubeの動画を背景に敷く(iOS・Android対応、自動再生・ループ) by Nakamura (@takayo-nakamura) on CodePen.

プレイヤーの設定

必要な設定は以下の通りです。
videoId:動画のID
playerVars:自動再生はイベントで行うので、playsinlineだけ設定します。
events:自動再生の代わりになるonReadyと、動画が終わった時にループさせるためのonStateChangeを設定します。

player = new YT.Player('player', {
      videoId: 'KxpSpBo0KC4',
      playerVars: {
        'playsinline': 1
       },
      events: {
      onReady: onPlayerReady,
      onStateChange: onPlayerStateChange
      }

イベント

onReady

プレイヤーの準備が整ったタイミングで実行されます。 ここでmute()とplayVideo()を実行する事によって、自動再生されるようになります。

function onPlayerReady (event) {
  event.target.mute()
  event.target.playVideo()
}

onStateChange

ステータスが状態が変更したタイミングで実行されます。
PlayerStateには種類がいくつかあります。
今回は終了したタイミングで実行したいので、
event.dataがYT.PlayerState.ENDEDの時に実行するようにします。
playVideo()を実行する事によって動画が再生されるので、これでループの処理になります。

function onPlayerStateChange (event) {
  if (event.data === YT.PlayerState.ENDED) {
    event.target.playVideo()
  }
}

終了以外についてはリファレンスを参考にしてください。

iframe 組み込みの YouTube Player API リファレンス  |  YouTube IFrame Player API  |  Google Developers

import文に対応したプレイヤー生成時の記述方法

APIが読み込まれ、準備が整ったタイミングで実行される関数 onYouTubeIframeAPIReady()は、importで読み込む仕様にしていると、 リファレンスの書き方では実行できません。(存在しないというエラーになります)

 function onYouTubeIframeAPIReady() {}

functionをwindow.に変える必要があります。

 window.onYouTubeIframeAPIReady = function () {}

エラー:YT.Player is not a constructorが出た時の対応

記述している中で、YT.Player is not a constructorというエラーが出ました。
インスタンスの生成がうまくいっていないようです。

こちらの記事を参考に修正しました。 https://www.codegrepper.com/code-examples/javascript/YT.Player+is+not+a+constructor

YT.ready(function () {
  // ここでプレイヤーのインスタンスを生成します。
}

スタイル

あとはCSSでサイズや位置を調整します。

背景に敷くので、z-index: -1;でコンテンツ要素よりも下に配置します。
また、操作や選択ができてしまうと困るので、
pointer-eventsとuser-selectをnoneにしておきます。

pointer-events: none;
user-select: none;