【JS】VIDEOタグで指定する動画をPCとスマホ用に切り替えるJavascript

目次

スマホとパソコンで動画を切り替えたい

動画の再生開始に影響するファイルサイズ

WEBページの背景に動画を使用するサイトを制作する際に気になるのが、埋め込んだ動画のファイルサイズ。

再生時間は15秒から30秒で、ファイルサイズは10MBを基準と考えています。

『ファイル容量を小さくしながらも高画質にしたい』と思いますが、10MB前後を目指すとビットレートを1Mbps~2Mbpsまで落とさなければなりません。ここまで落とすと当然画質は悪くなるですが、背景イメージとしてはギリギリ許容できる画質で、再生時間が30秒前後で何とか10MB前後に収めることができます。

パソコンサイトは通信環境が整っている事が多いので問題ないと思うのですが、スマホなど回線速度が遅いとそうはいきません。たかが10MBでも動画の読込に時間がかかり、自動再生による再生開始が遅くなります。

スマートフォンやタブレットは画面サイズも小さいので、Bootstrap5 のグリッドシステムのブレークポイントを基準にして動画の解像度を考えると、横幅576ピクセル~768ピクセル、大きくても992ピクセルに対応できる解像度のものがあればよく、480p(854×480 SD画質)または360p(640×360)の動画を用意すればいいかと思います。この解像度で、ビットレート500kbpsまで下げると、約3MBくらいまでファイルサイズが落ちます。画質は当然悪くなりますが、スマホの画面での背景動画としてはギリギリ観るに耐えれる範囲かと思います。

パソコンとスマホ用に用意した2つの動画ファイル

レスポンシブサイト制作時の画面サイズと埋め込み動画の解像度の参考値」を参考に、制作中のレスポンシブサイトのブレークポイントをsm(768px)としたため、これを境に以下の解像度の異なる動画を用意しました。

  • パソコン用 ... フルHD(1920×1080) MP4・WebM 約10MB
  • スマーフォン用 ... 480p(854×480 ) MP4・WebM 約3MB

この二つをレスポンシブサイトにvideoタグで動画を埋め込み、アクセスしてきた画面サイズに応じて再生する方法がないかと探してみると、jQueryを使って切り替える方法がありました。

jQueryで画面サイズによって切り替える参考

ソース例

上記ページのソースを参考に、以下のソースでアクセスしてきたデバイスの画面サイズが768ピクセルを境に再生する動画を切り替えることができました。class="switch"を付ければ、複数の<video>で埋め込んだ動画があっても対応できそうです。

  • 動画のファイル名は最後尾を_sp_pcにします。
  • <source>タグ内にclass="switch"を設定します。
  • この例は動画の遅延読込に Lozad.js を使用しているので、ソース指定にdata-srcとしていますので、Javascript内のsrcdata-srcに変更しています。
<video playsinline autoplay loop muted preload="auto" class="lozad" poster="img/poster.png"/>
   <source type="video/webm" src="" data-src="video_sp.webm" class="switch">
   <source type="video/mp4" src="" data-src="video_sp.mp4" class="switch">
   <source type="video/webm" src="" data-src="video_pc.webm" class="switch">
   <source type="video/mp4" src="" data-src="video_pc.mp4" class="switch">
</video>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>

$(function() {
  // 切り替える対象にclass属性。
  var $elem = $('.switch');
  
  // 切り替えの対象のsrc属性の末尾の文字列。
  var sp = '_sp.';
  var pc = '_pc.';
  
  // 画像を切り替えるウィンドウサイズ。
  var replaceWidth = 768;
  
 function imageSwitch() {
  // ウィンドウサイズを取得する。
  var windowWidth = parseInt($(window).width());

 // ページ内にあるすべての`.switch`に適応される。
  $elem.each(function() {
  var $this = $(this);
  // ウィンドウサイズが768px以上であれば_spを_pcに置換する。
  if(windowWidth >= replaceWidth) {
  $this.attr('data-src', $this.attr('data-src').replace(sp, pc));

 // ウィンドウサイズが768px未満であれば_pcを_spに置換する。
  } else {
  $this.attr('data-src', $this.attr('data-src').replace(pc, sp));
  }
  });
}
 imageSwitch();

// 動的なリサイズは操作後0.2秒経ってから処理を実行する。
var resizeTimer;
$(window).on('resize', function() {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(function() {
    imageSwitch();
  }, 200);
  });
});

 

STUDIOで使いたいとき

ノーコードでホームページが制作できるSTUDIO(有料プラン)で制作したサイトのキービジュアルに背景動画を埋め込みたいときのJavascriptソース例。ChatGPTに手伝ってもらったソース。動画の遅延表示させるLozad.jsも併用しています。

Googleタグマネージャーで使うときのソース例

Google Tag Manager経由で以下のソースを使用するとうまくいきました。動画ファイルをSTUDIOにアップロードできないので、読み込みたい動画ファイル(MP4とWEBM)は外部のレンタルサーバーにアップロードしてあるものを使用します。STUDIOのBOX要素のIDにmvを設定し、JavascriptでVIDEOタグを挿入し、デバイスの画面幅に合わせてPC用とスマホ用を切り替えます。

Googleタグマネージャーのトリガーは「ページビュー」と「履歴の変更」の二つを設定してください。「ページビュー」のみだと、ブラウザの「戻る」ボタンで他のページから飛んできたときに発火しないので、その対策として「履歴の変更」が必要です。

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
<script>
  var observer = lozad();
  observer.observe();
</script>
<script>
// 動画がすでに追加されているかを確認する関数
function isVideoAdded() {
  return document.getElementById("mv").querySelector("video") !== null;
}

// 動画を追加する処理
function addVideo() {
  // すでに動画が追加されている場合は処理を中断
  if (isVideoAdded()) {
    return;
  }

  // 動画要素の作成
  var video = document.createElement("video");
  video.muted = true;
  video.autoplay = true;
  video.loop = true;
  video.setAttribute("playsinline", "");
  video.classList.add("lozad");

  // 最初のソース (WEBM) に "switch" クラスを追加
  var source1 = document.createElement("source");
  source1.src = "https://qwerty.work/mv_sp.webm";
  source1.setAttribute("data-src", "https://qwerty.work/mv_sp.webm");
  source1.type = "video/webm";
  source1.classList.add("switch");

  // 2つ目のソース (MP4) に "switch" クラスを追加
  var source2 = document.createElement("source");
  source2.src = "https://qwerty.work/mv_sp.mp4";
  source2.setAttribute("data-src", "https://qwerty.work/mv_sp.mp4");
  source2.type = "video/mp4";
  source2.classList.add("switch");

  // 動画にソースを追加
  video.appendChild(source1);
  video.appendChild(source2);

  // 動画をDOMに追加
  document.getElementById("mv").appendChild(video);

  // 動画の再生処理とエラーキャッチ
  video.play().catch(function(error) {
    console.error("Video play failed:", error);
  });
}

// ページビューまたは履歴変更時に呼び出す関数
addVideo();
</script>
<script>
// PCとスマホで動画ファイルを切り替える
$(function() {
  // クラス "switch" を持つ <source> タグを対象にする
  var $sources = $('.switch');
  
  // 切り替えの対象のsrc属性の末尾の文字列。
  var sp = '_sp.';
  var pc = '_pc.';
  
  // 動画を切り替えるウィンドウサイズ。
  var replaceWidth = 970;
  
  function videoSwitch() {
    // ウィンドウサイズを取得する。
    var windowWidth = parseInt($(window).width());

    // ページ内にあるすべての`.switch`(<source>タグ)に適応される。
    $sources.each(function() {
      var $this = $(this); // <source>要素

      // ウィンドウサイズが970px以上であれば_spを_pcに置換し、キャッシュバスティングを追加
      if (windowWidth >= replaceWidth) {
        $this.attr('src', $this.attr('data-src').replace(sp, pc));
      // ウィンドウサイズが970px未満であれば_pcを_spに置換し、キャッシュバスティングを追加
      } else {
        $this.attr('src', $this.attr('data-src').replace(pc, sp));
      }
    });

    // <video>要素全体を再ロードして、srcの変更を反映
    $('video').get(0).load(); // <video>要素のload()メソッドを呼び出す
  }

  videoSwitch();
  // 動的なリサイズは操作後0.2秒経ってから処理を実行する。
  var resizeTimer;
  $(window).on('resize', function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function() {
      videoSwitch();
    }, 200);
  });
});
</script>

どうしてもカスタムコードで使いたいとき

Googleタグマネージャーの使い方がわからないので、STUDIOのカスタムコードに記載して使いたい場合はこちらのソース。発火のトリガーを複数設定しています。ページの遷移やブラウザによっては発火しないケースがあるかもしれません。

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
<script>
  var observer = lozad();
  observer.observe();
</script>
<script>
// 動画が既に追加されているか確認する関数
function isVideoAdded() {
  return document.getElementById("mv").querySelector("video") !== null;
}

// 共通の処理を関数として定義
function handleVideoLoad() {
  // 動画が既に追加されている場合は処理を中断
  if (isVideoAdded()) {
    return;
  }

  // 動画要素の作成
  var video = document.createElement("video");
  video.muted = true;
  video.autoplay = true;
  video.loop = true;
  video.setAttribute("playsinline", "");

  // クラス "lozad" を追加
  video.classList.add("lozad");

  // 最初のソース (WEBM) に "switch" クラスを追加
  var source1 = document.createElement("source");
  source1.src = "https://qwerty.work/mv_sp.webm";
  source1.setAttribute("data-src", "https://qwerty.work/mv_sp.webm");
  source1.type = "video/webm";
  source1.classList.add("switch");

  // 2つ目のソース (MP4) に "switch" クラスを追加
  var source2 = document.createElement("source");
  source2.src = "https://qwerty.work/mv_sp.mp4";
  source2.setAttribute("data-src", "https://qwerty.work/mv_sp.mp4");
  source2.type = "video/mp4";
  source2.classList.add("switch");

  // 動画にソースを追加
  video.appendChild(source1);
  video.appendChild(source2);

  // 動画をDOMに追加
  document.getElementById("mv").appendChild(video);

  // 動画の再生処理とエラーキャッチ
  video.play().catch(function(error) {
    console.error("Video play failed:", error);
  });
}

// ページが完全にロードされた時
window.addEventListener("load", handleVideoLoad);

// ページのHTMLが読み込まれた時
document.addEventListener("DOMContentLoaded", handleVideoLoad);

// ブラウザの履歴が変更された時(戻るボタン、進むボタンなど)
window.addEventListener("popstate", handleVideoLoad);
</script>
<script>
// PCとスマホで動画ファイルを切り替える
$(function() {
  // クラス "switch" を持つ <source> タグを対象にする
  var $sources = $('.switch');
  
  // 切り替えの対象のsrc属性の末尾の文字列。
  var sp = '_sp.';
  var pc = '_pc.';
  
  // 動画を切り替えるウィンドウサイズ。
  var replaceWidth = 970;
  
  function videoSwitch() {
    // ウィンドウサイズを取得する。
    var windowWidth = parseInt($(window).width());

    // ページ内にあるすべての`.switch`(<source>タグ)に適応される。
    $sources.each(function() {
      var $this = $(this); // <source>要素

      // ウィンドウサイズが970px以上であれば_spを_pcに置換
      if (windowWidth >= replaceWidth) {
        $this.attr('src', $this.attr('data-src').replace(sp, pc));
      // ウィンドウサイズが970px未満であれば_pcを_spに置換
      } else {
        $this.attr('src', $this.attr('data-src').replace(pc, sp));
      }
    });

    // <video>要素全体を再ロードして、srcの変更を反映
    $('video').get(0).load(); // <video>要素のload()メソッドを呼び出す
  }

  videoSwitch();
  // 動的なリサイズは操作後0.2秒経ってから処理を実行する。
  var resizeTimer;
  $(window).on('resize', function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function() {
      videoSwitch();
    }, 200);
  });
});
</script>

その他参考

jQueryに依存しない以下のJavascriptも見つけましたが、設定や設置方法が悪いのか、うまくいきませんでした。

画面サイズで切り替える例

ユーザーエージェントで切り替える例

前へ

スマホで電話番号などに自動的にリンクが付くのを防ぐ方法

次へ

レスポンシブサイト制作時の画面サイズと埋め込み動画の解像度の参考値