【要望】YouTube動画をウェビナー配信しているように見せたい

2022年11月04日

こんにちは、いとです。

先日、下記のコーディング依頼を受けました。

  • 指定時間になったらYouTube動画を「音声あり」で自動再生したい
  • 指定時刻以降のウェビナー開催中にアクセスがあった場合、経過時間分進めて動画を自動再生したい
  • 指定時間になるまでは動画の自動再生時刻までのカウントダウンを表示したい
  • 動画の自動再生が終わったら、ウェビナー終了のアナウンスを流したい

アクセシビリティやデータ容量等の観点から、ブラウザによって自動再生が制御されています。
「音声あり」だと自動再生できるブラウザが非常に限定されます。
そのため、クライアントには「音声なし」の自動再生で納得してもらいました。
参考:https://developers.google.com/youtube/iframe_api_reference?hl=ja#Mobile_considerations

が、そうであっても、YouTubeの自動再生設定がなかなかに面倒だったので、備忘録を兼ねて記事にしてみました。

まずは作成したソースコードから。

See the Pen YouTubeLIVEもどき by いと (@ykllog) on CodePen.

※Andorid10のChrome等、一部ブラウザでは自動再生されません。

処理としては下記の通りです。

  • 現在時間を取得(1秒毎に現在時刻を再取得)
  • 取得した時間が特定の時刻(以下、A時刻)より前だったら、カウントダウンを表示
  • A時刻と同じだったら動画を自動再生
  • A時刻以降だったら、A時刻からの経過時間分動画の再生時刻を進めた上で自動再生開始
  • A時刻以降で、A時刻からの経過時間が再生する動画の時間を超えていたらウェビナー終了アナウンスを表示

このうち、動画の自動再生についてはソースコードの下記の部分になります。

const tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

let player;
let youtubePlayer = function onYouTubeIframeAPIReady() {
  player = new YT.Player('youtube', { //youtubeはHTMLのid属性の値と同じ
    videoId: youtubeId,
    height: '100%',
    width: '100%',
    playerVars: {
      controls: 0, //コントロールバー
      autoplay: 1, //自動再生
      iv_load_policy: 3, //アノテーションを非表示
      rel: 0, //関連動画
      fs: 0, //全画面ボタン
      disablekb: 1, //キーボード操作
      modestbranding: 1, //YouTubeロゴ
      playsinline: 1, //インライン再生
    },
    events: {
      'onReady': onPlayerReady,
    },
  });
};

function onPlayerReady() {
  const elapsedTime = Math.floor((date.getTime() - start.getTime()) / 1000);

  if (elapsedTime > 0) {
    player.loadVideoById({
      videoId: youtubeId,
      startSeconds: elapsedTime,
    });
  } else {
    player.loadVideoById({
      videoId: youtubeId,
      startSeconds: 0,
    });
  }

  player.mute(); //再生時音声

  let embedCode = player.getVideoEmbedCode();
  if (document.getElementById('youtube').style.display = "block") {
    document.getElementById('youtube').innerHTML = embedCode;
  }
};

基本的には、IFrame Player APIのドキュメント通りに記載しています。
参考:https://developers.google.com/youtube/iframe_api_reference?hl=ja#Getting_Started

特筆すべき部分は、function onPlayerReady() {以降ですね。

const elapsedTime = Math.floor((date.getTime() - start.getTime()) / 1000);
上記で、現在時刻から開始時刻との差を出し、その値を1000で割ることで秒単位での経過時間を定義します。
またこの際、Math.floor関数を使用して値を整数値に変換しました。

ここで定義したelapsedTimeが0より大きければ、elapsedTime分進んだ時刻で動画を再生します。
そうでなければ、0秒目から動画を自動再生します。

あとは、動画の音声をオフにして、innerHTMLで指定の箇所にソースコードを書き込む処理です。

残念ながら、動作確認中にAndroid10のChromeでは自動再生されないことが発覚。
2022年9月時点ではAndroidのバージョン別シェア第二位だったこともあり、その他いろいろな方法を検討してvideoタグを使用したものに変わりました。

そのため使用に制限のあるソースコードですし、公開は悩んだのですが、YouToubeの自動再生に関する記事はほとんど見つけられなかったこと、あっても記事が古かったことから、公開することにしました。

作成時に参考にしたサイトは下記の通りです。
指定時間毎の表示振り分け → https://flex-box.net/set-date/
カウントダウンタイマー → https://mgmgblog.com/?p=2595
YouTubeの自動再生 → https://newsite-make.com/youtube-auto-play/

(おまけのvideoタグ関係)
https://developer.mozilla.org/ja/docs/Web/HTML/Element/video
https://developer.mozilla.org/ja/docs/Web/Media/Autoplay_guide
https://www.kakeru-d.jp/blog/html5-video-tag/

同じような依頼を受けた方の参考になれば幸いです。