【JavaScript】iPhone対応!動画を自動再生&ループさせる方法

WordPressでWebサイトを作る際、動画を効果的に使いたい場面は多いと思います。
特にファーストビューやヒーローヘッダーなどで動画を自動再生させたいケースはよくありますが、
iPhone(Safari、Chrome)では自動再生が制限されているため、正しく実装しないと「動画が再生されない」問題が起こります。

この記事では、特定のクラスを付与した動画を、
• iPhone対応の自動再生
• 無限ループ再生
• 自動再生できない場合のみネイティブの再生ボタンを表示

といった仕組みを解説します。

目次

実装イメージ

自分のiPhone13 miniの、ChromeとSafariで動作することを確認しています。

動画は自社サイトになります。

実装のポイント

1. muted / playsInline 属性を必ず付与

  • iPhone Safari で自動再生するには muted(無音) と playsInline(インラインでの再生) が必須です。
  • webkit-playsinlinex5-playsinlinex5-video-player-type="h5" などを追加すると iPhoneのSafari でも自動再生されます。
  • ただし現時点では、iPhone の Chrome では自動再生ができなかったため、JavaScript を利用して自動再生を実現します。

2. ユーザー操作後の再トライ

  • 初回ロードで再生できない場合もあるため、click や touchstart イベントで再挑戦できるようにするとユーザーにとって親切です。

3. 再生できない時のみ再生ボタンを表示

  • 再生中は邪魔にならないよう controls(再生ボタン)は非表示にし、再生できない場合のみフォールバックとして表示します。

HTML・PUGの書き方

以下を挿入します。
コードのポイントは以下になります。

  1. class=”js-video-loop” を付けることでスクリプトが適用されます。
  2. muted / playsinline / loop は必ず指定します。

HTMLの場合

<video class="js-video-loop" autoplay loop muted playsinline preload="auto" webkit-playsinline x5-playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true">
	<source src="./test.mp4" type="video/mp4">
</video>

PUGの場合

このコードのsrcの中に、自分のテンプレートで使用している「imgPath」を入れているので、
不要な場合は削除してください。

video.js-video-loop(src= imgPath + "test.mp4" loop autoplay muted playsinline preload="auto" webkit-playsinline x5-playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true")

JavaScriptのコード

JSファイルに以下を記述します。

// 【videoAutoLoop】iPhone(chrome、safariどちらも)でも自動再生+ループ。失敗時だけネイティブcontrolsを表示  
class AutoLoopVideo {
    constructor(videoElement) {
      if (!videoElement) return;
      this.video = videoElement;
      this.init();
    }

    init() {
      // 基本設定
      this.video.muted = true;
      this.video.loop = true;
      this.video.playsInline = true;
      // 初期はコントロール非表示(ボタンも出さない)
      this.setControls(false);

      // イベント
      this.video.addEventListener("loadedmetadata", () => this.handleLoaded());
      this.video.addEventListener("playing", () => this.setControls(false));
      this.video.addEventListener("play", () => this.setControls(false));
      this.video.addEventListener("pause", () => this.setControls(true)); // 一時停止時は出す
      this.video.addEventListener("ended", () => this.handleEnded());
      this.video.addEventListener("error", (e) => this.handleError(e));

      // 初回ユーザー操作で自動再生再トライ
      const onceTry = () => this.tryAutoplay();
      document.addEventListener("click", onceTry, { once: true });
      document.addEventListener("touchstart", onceTry, { once: true });
    }

    handleLoaded() {
      this.tryAutoplay();
    }

    handleEnded() {
      // ループを確実に
      this.video.currentTime = 0;
      this.video.play().catch(() => {
        // 自動再生がブロックされたらネイティブボタンを出す
        this.setControls(true);
      });
    }

    handleError(error) {
      console.error("動画エラー:", error);
      this.setControls(true);
    }

    tryAutoplay() {
      this.video
        .play()
        .then(() => this.setControls(false))
        .catch(() => this.setControls(true)); // ブロック時はネイティブcontrols表示
    }

    setControls(show) {
      // 再生中は非表示、必要時のみ表示
      this.video.controls = !!show;
      // もしcontrolsListを使ってダウンロード等を隠したい場合は以下
      // this.video.setAttribute("controlsList", "nodownload noplaybackrate");
    }
  }

  // 使用例(複数動画対応)
  document.addEventListener("DOMContentLoaded", () => {
    const videos = document.querySelectorAll(".js-video-loop");
    videos.forEach((video) => {
      new AutoLoopVideo(video);
    });
  });

まとめ

  • iPhoneでの動画自動再生には muted + playsInline が必須。
  • 自動再生が失敗しても、ネイティブの再生ボタン(controls)をフォールバックで表示すればユーザーに優しい。
  • .js-video-loop クラスを使うことで、複数動画にまとめて適用できる。
WEBもがき道場

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
目次