Back

Reactで動画を埋め込む方法

Reactで動画を埋め込む方法

ReactアプリでVideoを埋め込むのは一見シンプルに思えますが、autoplayが動作しない、iframeがレスポンシブにならない、<embed> タグがうまく機能しないといった問題に直面しがちです。本ガイドでは、最も実用的な2つのアプローチを紹介します。すなわち、自己ホスト型ファイル向けのネイティブHTML5 <video> 要素と、YouTubeやVimeoなどのプラットフォーム向けの <iframe> 埋め込みです。サードパーティ製ライブラリは、デフォルトではなく、本当に価値を発揮する場面でのみ言及します。

重要なポイント

  • 自己ホスト型ファイルにはネイティブのHTML5 <video> 要素を使用する。ライブラリは不要。
  • YouTube埋め込みでは、youtube-nocookie.com を指す素のままの <iframe> が標準的かつプライバシーに配慮したアプローチ。
  • autoplayをChrome、Safari、Firefoxで確実に動作させるには muted 属性が必要。
  • iOSで強制的なフルスクリーン再生を防ぐには playsInline が不可欠。
  • ReactPlayerのようなライブラリは、複数プロバイダーを横断した統一APIや高度なイベントコールバックが必要な場合にのみ採用する。

方法1: 自己ホスト型ファイルのためのReactにおけるHTML5 Video

動画ファイルを自分で管理しているのであれば、ネイティブの <video> 要素が最適なツールです。ライブラリは不要です。

import myVideo from './assets/demo.mp4';

export default function VideoPlayer() {
  return (
    <video
      width="100%"
      style={{ aspectRatio: '16/9' }}
      controls
      playsInline
      muted
    >
      <source src={myVideo} type="video/mp4" />
      <track
        kind="subtitles"
        src="/captions/demo.en.vtt"
        srcLang="en"
        label="English"
        default
      />
      Your browser does not support the video tag.
    </video>
  );
}

押さえておきたいポイントをいくつか挙げます。

  • autoPlay を確実に動作させるには muted が必要 です。Chrome、Safari、Firefoxはいずれも、ミュートされていないautoplayをデフォルトでブロックします。muted なしで動作すると思い込まないようにしましょう。なお、JSXではこの属性はキャメルケースで autoPlay と記述し、autoplay ではありません。ブラウザのサポート状況とautoplayポリシーは Can I Use に記載されています。
  • playsInline は、iOSで動画が自動的にフルスクリーンで開くのを防ぐために必要です。
  • <track> はキャプションや字幕を追加します。動画コンテンツのアクセシビリティを担保する正しい方法であり、見落としやすい部分でもあります。
  • <video> 内のフォールバックテキストは、要素を認識しない非常に古いブラウザでのみ表示されます。それでも記載しておく価値はあります。

HLS (.m3u8) のような アダプティブストリーミング形式 については、ブラウザのネイティブサポートは異なります。SafariはHLSをネイティブで処理できますが、ChromeとFirefoxではストリームを解析・再生するために hls.js のようなライブラリが必要です。

ReactでのYouTube埋め込み: iframeを使用する

YouTubeやVimeoの場合は、<iframe> が標準的なアプローチです。これにReact専用パッケージは必要ありません。

export default function YouTubeEmbed({ videoId }) {
  return (
    <div style={{ aspectRatio: '16/9', width: '100%' }}>
      <iframe
        width="100%"
        height="100%"
        src={`https://www.youtube-nocookie.com/embed/${videoId}`}
        title="YouTube video player"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
        allowFullScreen
        style={{ border: 'none' }}
      />
    </div>
  );
}

主なポイント:

  • 埋め込みURLには youtube.com ではなく youtube-nocookie.com を使用 します。これはYouTubeのプライバシー強化モードで、ユーザーがプレーヤーを操作するまでトラッキングクッキーを抑制します。
  • iframeにはスクリーンリーダーのために title が必須 です。これがないと、支援技術が埋め込みコンテンツを説明する手段を失います。
  • ラッパーに aspectRatio: '16/9' を指定し、iframeに width: 100%height: 100% を設定するのが、モダンCSSを用いた最もクリーンなレスポンシブ手法です。paddingハックは不要です。CSSの aspect-ratio プロパティのブラウザサポート状況は Can I Use で確認できます。
  • 埋め込みURLの形式は https://www.youtube-nocookie.com/embed/{VIDEO_ID} です。動画IDは、標準的なYouTube URLの v クエリパラメータの値です(例えば youtube.com/watch?v=VIDEO_ID?v= の後の部分)。

クエリ文字列で追加パラメータを渡すことができます:

/embed/VIDEO_ID?controls=1&rel=0

React Video Playerライブラリを使うべきタイミング

ほとんどのユースケースでは、ネイティブの <video> 要素や素のiframeで十分です。複数のプラットフォーム(YouTube、Vimeo、Wistia、HLS、DASH)を統一APIを持つ単一コンポーネントでサポートする必要がある場合、または異なるプロバイダー間で onReadyonProgressonEnded といったイベントコールバックが必要な場合は、ReactPlayer のようなライブラリを検討してください。

ReactPlayerはバンドルサイズに無視できない影響を与えるため、依存関係として追加する前に、その柔軟性が本当に必要かを評価する価値があります。

まとめ

まずは最もシンプルに動作するツールから始めましょう。自己ホスト型動画なら、HTML5 <video> 要素に controlsplaysInline を付け、autoplayが必要なら muted を加えます。ReactでのYouTube埋め込みなら、youtube-nocookie.com を指し、適切な title 属性を持つ素の <iframe> で十分です。ライブラリは、ネイティブのアプローチでは本当に対応しきれない場合にのみ採用してください。

FAQ

モダンブラウザは音声付き動画のautoplayをブロックします。Chrome、Safari、Firefoxでautoplayを確実に動作させるには、video要素にautoPlayと一緒にmuted属性を含める必要があります。iOSではさらにplaysInlineが必要で、これがないと動画がインライン再生を拒否したりフルスクリーンで開いたりすることがあります。これらが揃っていないと、autoplayは静かに失敗します。

可能な限りyoutube-nocookie.comを使用してください。これはYouTubeのプライバシー強化埋め込みモードであり、ユーザーが実際にプレーヤーを操作するまでトラッキングクッキーの設定を回避します。コア再生機能は標準埋め込みとほぼ同じですが、プライバシーコンプライアンスに優しく、サイト上のサードパーティクッキー警告を減らすのに役立ちます。

一般的なユースケースでは不要です。ネイティブのHTML5 video要素は自己ホスト型ファイルに対応し、素のiframeはYouTubeやVimeoに対応します。ReactPlayerは、複数プロバイダーを横断する統一APIや、onProgressやonEndedといった一貫したイベントコールバックが必要な場合にのみ採用してください。それ以外の場合、バンドルコストが正当化されることはほとんどありません。

動画またはiframeを、aspectRatioを16/9、widthを100%に設定したコンテナでラップします。次に、内側の要素にwidth 100%とheight 100%を設定します。このモダンCSSアプローチは古いpadding-bottomハックを置き換え、手動計算なしであらゆる画面サイズで動画の比率を保ちます。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay