HTMLのvideoタグの使い方!自動再生・再生ボタン・レスポンシブ

再生・停止・音量・速度のカスタムビデオコントロールのUIとJavaScript実装コードの例
いつまで無駄なデザインに時間を費やしますか? 自作コード × SWELL
理想のサイトをカスタマイズ構築

面倒な基本構造やレスポンシブ対応はテーマに任せ、浮いた時間で「あなたにしかできないこだわりの独自カスタマイズ」をとことん追求してみませんか?

「SWELL」の徹底レビュー・詳細を見る
※当サイトはアフィリエイト広告(SWELLプロモーション)を利用しています

HTMLの<video>タグは、プラグインなしでWebサイトに動画を埋め込む必須要素です。

本記事では、基本の記述方法からスマホ環境での自動再生ループ、CSSによる背景動画化、JavaScriptを用いたカスタムプレイヤーの実装などを解説します。

また、HTMLに関するカテゴリーページから学びたい内容を決めたい人は、以下のHTMLページをご確認ください。

目次
もう無駄なレイアウトに凝るのやめたら? 最速の土台 × 独自CSS
SWELLをゴリゴリにカスタマイズ

レスポンシブ対応や基本レイアウトは最高峰テーマに任せませんか?浮いた時間で、流麗なアニメーションや標準設定を上書きする「あなただけの高度なビジュアル表現」をとことん突き詰めましょう。

「SWELL」であなたのデザインの限界を超える
※当サイトはアフィリエイト広告(SWELLプロモーション)を利用しています

videoタグとは:書き方と対応形式

HTML5から導入されたvideoタグは、ブラウザ標準機能だけでWebページに動画を埋め込める要素です。

Webサイト制作においてvideoタグは、ヒーローエリアの背景動画、商品の使い方を解説するプロモーション映像などあらゆる場面で利用されています。

ここでは、videoタグの基本的な知識、実務でそのまま使えるサンプルコード、動画ソースの適切な取り扱い方を解説します。

videoタグとは:書き方と対応形式
  • videoタグの役割とsrcsourceによる動画ファイルの指定
  • 対応フォーマットと非対応形式

videoタグの役割とsrc・sourceによる動画ファイルの指定

Webページ上に動画を配置して埋め込む記述方法には、大きく分けて2つのアプローチがあります。

1つは<video>タグに直接属性を書くシンプルな方法、もう1つは<video>タグの中に<source>タグを使って動画ファイルを指定する方法です。

🎬 sourceタグを使った動画の指定

⭕️ 複数の形式を用意する実装

🔊
<!– ❌ 悪い例:1つの形式しか指定できない –>
<video src=”movie.mp4″ controls></video>

<!– ⭕️ 良い例:複数の形式とエラーメッセージを用意する –>
<video controls width=”100%”>
  <!– ブラウザは上から順に再生可能なものを探します –>
  <source src=”movie.webm” type=”video/webm”>
  <source src=”movie.mp4″ type=”video/mp4″>
  
  <!– どの形式も再生できない古いブラウザ向けのメッセージ –>
  <p>お使いのブラウザは動画の再生に対応していません。
  <a href=”movie.mp4″>動画をダウンロード</a>してください。</p>
</video>
HTMLコード表示
<div class="hvideo-sec1-wrapper">
  
  <div class="hvideo-sec1-demo-area">
    <div class="hvideo-sec1-box">
      <div class="hvideo-sec1-label">🎬 sourceタグを使った動画の指定</div>
      
      <div class="hvideo-sec1-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 10px 0;">⭕️ 複数の形式を用意する実装</p>
        
        <div class="hvideo-sec1-mock-player">
          <div class="hvideo-sec1-mock-screen">
            <span style="font-size:30px; color:#fff;">▶</span>
          </div>
          <div class="hvideo-sec1-mock-controls">
            <span class="hvideo-sec1-mock-btn">▶</span>
            <div class="hvideo-sec1-mock-bar"></div>
            <span class="hvideo-sec1-mock-btn">🔊</span>
          </div>
        </div>
      </div>

      <div class="hvideo-sec1-code">
        <!-- ❌ 悪い例:1つの形式しか指定できない --><br>
        <video <span class="hvideo-sec1-hl-red">src="movie.mp4"</span> controls></video><br><br>
        
        <!-- ⭕️ 良い例:複数の形式とエラーメッセージを用意する --><br>
        <span class="hvideo-sec1-hl-blue"><video controls width="100%"></span><br>
          <!-- ブラウザは上から順に再生可能なものを探します --><br>
          <span class="hvideo-sec1-hl-green"><source src="movie.webm" type="video/webm"></span><br>
          <span class="hvideo-sec1-hl-green"><source src="movie.mp4" type="video/mp4"></span><br>
          <br>
          <!-- どの形式も再生できない古いブラウザ向けのメッセージ --><br>
          <p>お使いのブラウザは動画の再生に対応していません。<br>
          <a href="movie.mp4">動画をダウンロード</a>してください。</p><br>
        <span class="hvideo-sec1-hl-blue"></video></span>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-sec1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-sec1-mock-player {
  background-color: #000;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.hvideo-sec1-mock-screen {
  height: 150px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #212529;
}
.hvideo-sec1-mock-controls {
  background-color: #343a40;
  display: flex;
  align-items: center;
  padding: 10px;
  gap: 10px;
}
.hvideo-sec1-mock-btn {
  color: #fff;
  font-size: 12px;
}
.hvideo-sec1-mock-bar {
  flex-grow: 1;
  height: 4px;
  background-color: #6c757d;
  border-radius: 2px;
  position: relative;
}
.hvideo-sec1-mock-bar::after {
  content: '';
  position: absolute;
  top: 0; left: 0;
  height: 100%; width: 40%;
  background-color: #0d6efd;
  border-radius: 2px;
}
.hvideo-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-sec1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-sec1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-sec1-hl-red { color: #e06c75; font-weight: bold; }

対応フォーマットと非対応形式

動画をWebサイトに埋め込む上で理解しておかなければならないのが、ブラウザがサポートしている動画フォーマットと正しいメディアタイプの指定です。

Webサイトで動画を扱う場合は、ブラウザで再生可能なmp4形式に変換(エンコード)して使用してください。

さらに表示速度を極めたい場合は、Googleが開発した軽量で高画質なwebm形式をメインに設定し、予備としてmp4を配置するのが現代のベストプラクティスです。

📦 動画フォーマットの正しい使い分け
推奨 .webm

軽量・高画質。
優先して読み込ませる。

必須 .mp4

全ブラウザ対応。
必ず用意する標準形式。

NG .mov / .avi

スマホやPCの環境によって
再生エラーになる危険性あり。

<video controls>
  <!– 💡 優先度1:容量が軽く表示が早い WebM を上に書く –>
  <source src=”video.webm” type=”video/webm“>

  <!– 💡 優先度2:WebM非対応ブラウザ(古いSafari等)向けの MP4 –>
  <source src=”video.mp4” type=”video/mp4“>

  <!– ❌ 絶対に書いてはいけない形式(変換ツールでMP4にする) –>
  <!– <source src=”video.mov” type=”video/quicktime”> –>
  <!– <source src=”video.avi” type=”video/x-msvideo”> –>
</video>
HTMLコード表示
<div class="hvideo-sec2-wrapper">
  
  <div class="hvideo-sec2-demo-area">
    <div class="hvideo-sec2-box">
      <div class="hvideo-sec2-label">📦 動画フォーマットの正しい使い分け</div>
      
      <div class="hvideo-sec2-visual">
        <div class="hvideo-sec2-format-grid">
          <div class="hvideo-sec2-format-item hvideo-sec2-format-ok">
            <span class="hvideo-sec2-badge-ok">推奨</span>
            <strong>.webm</strong>
            <p>軽量・高画質。<br>優先して読み込ませる。</p>
          </div>
          <div class="hvideo-sec2-format-item hvideo-sec2-format-ok">
            <span class="hvideo-sec2-badge-ok">必須</span>
            <strong>.mp4</strong>
            <p>全ブラウザ対応。<br>必ず用意する標準形式。</p>
          </div>
          
          <div class="hvideo-sec2-format-item hvideo-sec2-format-ng">
            <span class="hvideo-sec2-badge-ng">NG</span>
            <strong>.mov / .avi</strong>
            <p>スマホやPCの環境によって<br>再生エラーになる危険性あり。</p>
          </div>
        </div>
      </div>

      <div class="hvideo-sec2-code">
        <video controls><br>
          <!-- 💡 優先度1:容量が軽く表示が早い WebM を上に書く --><br>
          <source src="video<span class="hvideo-sec2-hl-green">.webm</span>" type="<span class="hvideo-sec2-hl-blue">video/webm</span>"><br><br>
        
          <!-- 💡 優先度2:WebM非対応ブラウザ(古いSafari等)向けの MP4 --><br>
          <source src="video<span class="hvideo-sec2-hl-green">.mp4</span>" type="<span class="hvideo-sec2-hl-blue">video/mp4</span>"><br><br>
        
          <!-- ❌ 絶対に書いてはいけない形式(変換ツールでMP4にする) --><br>
          <!-- <source src="video<span class="hvideo-sec2-hl-red">.mov</span>" type="video/quicktime"> --><br>
          <!-- <source src="video<span class="hvideo-sec2-hl-red">.avi</span>" type="video/x-msvideo"> --><br>
        </video>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-sec2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 550px;
  border-radius: 4px;
}
.hvideo-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-sec2-format-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.hvideo-sec2-format-item {
  padding: 15px;
  border-radius: 4px;
  background-color: #fff;
  border-left: 4px solid #ccc;
  position: relative;
}
.hvideo-sec2-format-ok {
  border-left-color: #198754;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.hvideo-sec2-format-ng {
  border-left-color: #dc3545;
  background-color: #f8d7da;
}
.hvideo-sec2-format-item strong {
  display: block;
  font-size: 16px;
  color: #212529;
  margin-bottom: 5px;
}
.hvideo-sec2-format-item p {
  margin: 0;
  font-size: 12px;
  color: #495057;
  line-height: 1.4;
}
.hvideo-sec2-badge-ok {
  position: absolute;
  top: 15px; right: 15px;
  background-color: #198754;
  color: white;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: bold;
}
.hvideo-sec2-badge-ng {
  position: absolute;
  top: 15px; right: 15px;
  background-color: #dc3545;
  color: white;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: bold;
}
.hvideo-sec2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hvideo-sec2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-sec2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-sec2-hl-red { color: #e06c75; font-weight: bold; }

スマホ対応必須:自動再生とループの設定

Webサイトのファーストビューなどで、背景として動画を動かし続ける「自動再生」や「ループ」の演出は、Webデザインにおいて定番の手法です。

タグにautoplayloop属性を追加するだけの簡単な作業に思えます。

しかし、実際にはモバイルデバイス特有の厳格な仕様が存在し、属性をつけただけでは「スマホで見たら動画が止まったままになっている」という事故が多発します。

ここでは、PCだけでなくスマートフォン環境でも自動再生を機能させる必須属性と再生されない時の原因・対策を解説します。

スマホ対応必須:自動再生とループの設定
  • autoplaymutedplaysinlineの組み合わせ
  • iPhoneやスマホで自動再生されない原因と対策

autoplay・muted・playsinlineの組み合わせ

背景動画やUIの装飾として動画を無音で自動ループさせる場合、つまづきやすいのが「PCのChromeでは自動再生されたからOK」とテストを終えてしまうミスです。

動画を背景として自動再生させるには、autoplay muted playsinline loopの4点セットを一緒に記述してください。

※なお、ユーザーの操作を待ってから再生させたい場合は、autoplay属性を記述しないだけで機能します。

🔄 スマホ対応の自動再生・ループ設定

⭕️ 背景動画で必須となる「4点セット」

🎞️
無音で永遠にループ再生中…
Main Visual
<!– ❌ 危険:スマホで再生されない、全画面になる –>
<video src=”bg.mp4″ autoplay loop></video>

<!– ⭕️ 安全:実務で必ず使う鉄壁の4点セット –>
<video
  src=”bg.mp4″
  autoplay <!– 自動再生 –>
  muted <!– ★スマホ必須:無音にする –>
  playsinline <!– ★iPhone必須:全画面化を防ぐ –>
  loop <!– ループ再生 –>
></video>

<!– 💡 補足:自動再生させない場合は単に外すだけ –>
<video src=”movie.mp4″ controls playsinline></video>
HTMLコード表示
<div class="hvideo-auto1-wrapper">
  
  <div class="hvideo-auto1-demo-area">
    <div class="hvideo-auto1-box">
      <div class="hvideo-auto1-label">🔄 スマホ対応の自動再生・ループ設定</div>
      
      <div class="hvideo-auto1-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 背景動画で必須となる「4点セット」</p>
        
        <div class="hvideo-auto1-mock-bg">
          <div class="hvideo-auto1-mock-video-area">
            <span style="font-size:24px;">🎞️</span>
            <div style="font-size:12px; margin-top:5px; color:#fff;">無音で永遠にループ再生中...</div>
          </div>
          <div class="hvideo-auto1-mock-text">Main Visual</div>
        </div>
      </div>

      <div class="hvideo-auto1-code">
        <!-- ❌ 危険:スマホで再生されない、全画面になる --><br>
        <video src="bg.mp4" <span class="hvideo-auto1-hl-red">autoplay loop</span>></video><br><br>
        
        <!-- ⭕️ 安全:実務で必ず使う鉄壁の4点セット --><br>
        <span class="hvideo-auto1-hl-blue"><video</span> <br>
          src="bg.mp4" <br>
          <span class="hvideo-auto1-hl-green">autoplay</span>      <span class="hvideo-auto1-hl-comment"><!-- 自動再生 --></span><br>
          <span class="hvideo-auto1-hl-green">muted</span>         <span class="hvideo-auto1-hl-comment"><!-- ★スマホ必須:無音にする --></span><br>
          <span class="hvideo-auto1-hl-green">playsinline</span>   <span class="hvideo-auto1-hl-comment"><!-- ★iPhone必須:全画面化を防ぐ --></span><br>
          <span class="hvideo-auto1-hl-green">loop</span>          <span class="hvideo-auto1-hl-comment"><!-- ループ再生 --></span><br>
        <span class="hvideo-auto1-hl-blue">></video></span><br><br>

        <!-- 💡 補足:自動再生させない場合は単に外すだけ --><br>
        <video src="movie.mp4" controls playsinline></video>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-auto1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-auto1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-auto1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-auto1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-auto1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-auto1-mock-bg {
  position: relative;
  width: 100%;
  height: 120px;
  background-color: #212529;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}
.hvideo-auto1-mock-video-area {
  position: absolute;
  top: 0; left: 0; width: 100%; height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  opacity: 0.5;
  background-image: repeating-linear-gradient(45deg, #343a40 25%, transparent 25%, transparent 75%, #343a40 75%, #343a40), repeating-linear-gradient(45deg, #343a40 25%, #212529 25%, #212529 75%, #343a40 75%, #343a40);
  background-size: 20px 20px;
}
.hvideo-auto1-mock-text {
  position: relative;
  z-index: 2;
  color: #fff;
  font-size: 20px;
  font-weight: bold;
  letter-spacing: 2px;
}
.hvideo-auto1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-auto1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-auto1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-auto1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-auto1-hl-comment { color: #6c757d; font-style: italic; }

iPhoneやスマホで自動再生されない原因と対策

4点セット(autoplay muted playsinline loop)を書いたはずなのに、「iPhoneで確認したら自動再生されない」「スマホ実機で動かない」とパニックに陥るケースは実務でも多いです。

「低電力モードのユーザーには自動再生されないもの」と割り切るのが大前提です。

その上で、自動再生がブロックされてしまった場合、動画エリアが真っ黒な四角になるのを防ぐため、poster属性を使用して「動画が再生される代わりの画像」を設定しておくのがよいです。

🔋 低電力モードによる自動再生ブロック対策

⚠️ 自動再生がブロックされた場合の見た目

❌ poster設定なし

(真っ黒・無反応)

⭕️ poster設定あり

綺麗な代替画像
が表示される
<!– 💡 動画が動かない時は poster に指定した画像を表示 –>
<video
  src=”main-visual.mp4″
  poster=”fallback-image.jpg” <!– ★これが命綱! –>
  autoplay muted playsinline loop
></video>

/* 💡 (補足知識)JavaScriptでのエラー検知と再生 */
const video = document.querySelector(‘video’);
const playPromise = video.play();

if (playPromise !== undefined) {
  playPromise.catch(error => {
    // 自動再生がブロックされた場合の処理
    // (例: 代わりに「再生ボタン」を画面に出す等)
    console.log(“自動再生がブロックされました”);
  });
}
HTMLコード表示
<div class="hvideo-auto2-wrapper">
  
  <div class="hvideo-auto2-demo-area">
    <div class="hvideo-auto2-box">
      <div class="hvideo-auto2-label">🔋 低電力モードによる自動再生ブロック対策</div>
      
      <div class="hvideo-auto2-visual">
        <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⚠️ 自動再生がブロックされた場合の見た目</p>
        
        <div style="display:flex; gap:10px; justify-content:center;">
          <div style="flex:1;">
            <p style="font-size:11px; text-align:center; color:#666; margin:0 0 5px 0;">❌ poster設定なし</p>
            <div class="hvideo-auto2-mock-noposter">
              <span>(真っ黒・無反応)</span>
            </div>
          </div>
          
          <div style="flex:1;">
            <p style="font-size:11px; text-align:center; color:#666; margin:0 0 5px 0;">⭕️ poster設定あり</p>
            <div class="hvideo-auto2-mock-poster">
              <span>綺麗な代替画像<br>が表示される</span>
            </div>
          </div>
        </div>
      </div>

      <div class="hvideo-auto2-code">
        <!-- 💡 動画が動かない時は poster に指定した画像を表示 --><br>
        <span class="hvideo-auto2-hl-blue"><video</span> <br>
          src="main-visual.mp4" <br>
          <span class="hvideo-auto2-hl-red">poster="fallback-image.jpg"</span> <span class="hvideo-auto2-hl-comment"><!-- ★これが命綱! --></span><br>
          autoplay muted playsinline loop<br>
        <span class="hvideo-auto2-hl-blue">></video></span><br><br>
        
        /* 💡 (補足知識)JavaScriptでのエラー検知と再生 */<br>
        <span class="hvideo-auto2-hl-blue">const</span> video = document.querySelector('video');<br>
        <span class="hvideo-auto2-hl-blue">const</span> playPromise = video.play();<br><br>
        <span class="hvideo-auto2-hl-blue">if</span> (playPromise !== undefined) {<br>
          playPromise.catch(error => {<br>
            <span class="hvideo-auto2-hl-comment">// 自動再生がブロックされた場合の処理</span><br>
            <span class="hvideo-auto2-hl-comment">// (例: 代わりに「再生ボタン」を画面に出す等)</span><br>
            console.log("自動再生がブロックされました");<br>
          });<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-auto2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-auto2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-auto2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 550px;
  border-radius: 4px;
}
.hvideo-auto2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-auto2-visual {
  background-color: #f1f3f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-auto2-mock-noposter {
  background-color: #000;
  height: 90px;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 10px;
}
.hvideo-auto2-mock-poster {
  background-color: #0d6efd;
  background-image: linear-gradient(135deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.1) 75%, transparent 75%, transparent);
  background-size: 20px 20px;
  height: 90px;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 10px;
  text-align: center;
  box-shadow: inset 0 0 10px rgba(0,0,0,0.2);
}
.hvideo-auto2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #dc3545;
}
.hvideo-auto2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-auto2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-auto2-hl-comment { color: #6c757d; font-style: italic; }

動画のサイズ調整とレスポンシブ・背景動画化

HTMLで<video>タグを配置した後は、サイトのデザインに合わせて見た目を整えるCSSの出番です。

Web制作では、PCでもスマートフォンでも画面に合わせて伸縮するレスポンシブ対応、画面いっぱいに広がる背景動画の実装が必須スキルになります。

ここでは、videoサイズの指定、CSSを用いたサイズ自動調整などを解説します。

動画のサイズ調整とレスポンシブ・背景動画化
  • 幅を100%にしてアスペクト比を維持する
  • object-fitを使った全画面背景動画
  • 角丸や枠線・影のデザイン調整

幅を100%にしてアスペクト比を維持する

動画のサイズを変更し、スマホ画面からはみ出さないように親要素にフィットさせる基本的なレスポンシブ設定です。

動画のアスペクト比を保ったままレスポンシブにするには、width: 100%;を指定し、高さはheight: auto;に設定します。

これにより、ブラウザが幅に合わせて高さを自動計算し、動画が歪まなくなります。

📱 アスペクト比を保ったレスポンシブ動画

❌ 悪い例:height: 100% で潰れてしまう

動画が潰れる

⭕️ 良い例:height: auto で比率をキープ

比率キープ(16:9)
<!– HTML –>
<div class=”video-wrap”>
  <video src=”movie.mp4″ class=”responsive-video”></video>
</div>

/* 💡 悪い例:動画が歪む */
.bad-video {
  width: 100%;
  height: 100%; /* ★絶対NG */
}

/* 💡 良い例:アスペクト比を維持して伸縮 */
.responsive-video {
  width: 100%;
  height: auto; /* ★ブラウザに高さを自動計算させる */
  display: block; /* 謎の余白(下部)を消すためのおまじない */
}
HTMLコード表示
<div class="hvideo-css1-wrapper">
  
  <div class="hvideo-css1-demo-area">
    <div class="hvideo-css1-box">
      <div class="hvideo-css1-label">📱 アスペクト比を保ったレスポンシブ動画</div>
      
      <div class="hvideo-css1-visual">
        <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ 悪い例:height: 100% で潰れてしまう</p>
        <div class="hvideo-css1-mock-container" style="height: 100px;">
          <div class="hvideo-css1-mock-video hvideo-css1-bad">動画が潰れる</div>
        </div>

        <p style="font-size:12px; color:#198754; font-weight:bold; margin:20px 0 5px 0;">⭕️ 良い例:height: auto で比率をキープ</p>
        <div class="hvideo-css1-mock-container">
          <div class="hvideo-css1-mock-video hvideo-css1-good">比率キープ(16:9)</div>
        </div>
      </div>

      <div class="hvideo-css1-code">
        <!-- HTML --><br>
        <span class="hvideo-css1-hl-blue"><div class="video-wrap"></span><br>
          <video src="movie.mp4" class="responsive-video"></video><br>
        <span class="hvideo-css1-hl-blue"></div></span><br><br>
        
        /* 💡 悪い例:動画が歪む */<br>
        <span class="hvideo-css1-hl-blue">.bad-video</span> {<br>
          width: 100%;<br>
          <span class="hvideo-css1-hl-red">height: 100%;</span> /* ★絶対NG */<br>
        }<br><br>

        /* 💡 良い例:アスペクト比を維持して伸縮 */<br>
        <span class="hvideo-css1-hl-blue">.responsive-video</span> {<br>
          <span class="hvideo-css1-hl-green">width: 100%;</span><br>
          <span class="hvideo-css1-hl-green">height: auto;</span> /* ★ブラウザに高さを自動計算させる */<br>
          display: block; /* 謎の余白(下部)を消すためのおまじない */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-css1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-css1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-css1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-css1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-css1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-css1-mock-container {
  width: 100%;
  border: 2px solid #0d6efd;
  background-color: #fff;
}
.hvideo-css1-mock-video {
  background-color: #212529;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 12px;
  font-weight: bold;
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.05) 75%, rgba(255,255,255,0.05)), repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.05) 75%, rgba(255,255,255,0.05));
  background-size: 20px 20px;
}
.hvideo-css1-bad {
  width: 100%;
  height: 100%; /* 親の100pxに潰される */
}
.hvideo-css1-good {
  width: 100%;
  aspect-ratio: 16 / 9; /* height:autoの代用モック */
}
.hvideo-css1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-css1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css1-hl-red { color: #e06c75; font-weight: bold; }

幅と高さの指定方法を詳しく知りたい人は「【html&css】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。

object-fitを使った全画面背景動画

Webサイトのトップページで、画面全体に動画を敷き詰め、その上に文字を乗せる「背景動画」は人気の高いレイアウトです。

背景動画を作るには、動画をposition: absolute;で画面いっぱいに広げた上で、object-fit: cover;を指定します。

これにより、動画の比率を保ったまま、余った部分を自動的にトリミング(切り抜き)して、画面(親要素)に隙間なくフィットできます。

🪟 object-fitを使った全画面背景動画

⭕️ 比率を崩さず、はみ出した分をトリミングして埋め尽くす

HERO SECTION

動画の上に文字が乗っています

<!– HTML –>
<div class=”hero-area”>
  <!– 💡 必須:自動再生ループの4点セット –>
  <video src=”bg.mp4″ class=”bg-video” autoplay muted playsinline loop></video>
  <div class=”hero-content”>動画の上の文字</div>
</div>

/* CSS */
.hero-area {
  position: relative; /* 子要素の基準点にする */
  height: 100vh; /* 画面の高さ100% */
  overflow: hidden; /* はみ出た動画を隠す */
}

.bg-video {
  position: absolute; /* 親要素に重なるように絶対配置 */
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: cover; /* 比率を保って隙間なく埋める */
  z-index: -1; /* 文字の裏側に回す */
}
HTMLコード表示
<div class="hvideo-css2-wrapper">
  
  <div class="hvideo-css2-demo-area">
    <div class="hvideo-css2-box">
      <div class="hvideo-css2-label">🪟 object-fitを使った全画面背景動画</div>
      
      <div class="hvideo-css2-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 比率を崩さず、はみ出した分をトリミングして埋め尽くす</p>
        
        <div class="hvideo-css2-hero-mock">
          <div class="hvideo-css2-video-mock"></div>
          
          <div class="hvideo-css2-content-mock">
            <div style="margin:0; font-size:20px; letter-spacing:2px;">HERO SECTION</div>
            <p style="margin:5px 0 0 0; font-size:12px;">動画の上に文字が乗っています</p>
          </div>
        </div>
      </div>

      <div class="hvideo-css2-code">
        <!-- HTML --><br>
        <span class="hvideo-css2-hl-blue"><div class="hero-area"></span><br>
          <span class="hvideo-css2-hl-comment"><!-- 💡 必須:自動再生ループの4点セット --></span><br>
          <video src="bg.mp4" class="bg-video" autoplay muted playsinline loop></video><br>
          <div class="hero-content">動画の上の文字</div><br>
        <span class="hvideo-css2-hl-blue"></div></span><br><br>

        /* CSS */<br>
        <span class="hvideo-css2-hl-blue">.hero-area</span> {<br>
          <span class="hvideo-css2-hl-green">position: relative;</span> /* 子要素の基準点にする */<br>
          height: 100vh;      /* 画面の高さ100% */<br>
          overflow: hidden;   /* はみ出た動画を隠す */<br>
        }<br><br>
        <span class="hvideo-css2-hl-blue">.bg-video</span> {<br>
          <span class="hvideo-css2-hl-green">position: absolute;</span> /* 親要素に重なるように絶対配置 */<br>
          top: 0; left: 0;<br>
          width: 100%; height: 100%;<br>
          <span class="hvideo-css2-hl-red">object-fit: cover;</span>  /* 比率を保って隙間なく埋める */<br>
          z-index: -1;        /* 文字の裏側に回す */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-css2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-css2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-css2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-css2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-css2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-css2-hero-mock {
  position: relative;
  width: 100%;
  height: 150px;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px solid #333;
}
.hvideo-css2-video-mock {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-color: #0d6efd;
  background-image: radial-gradient(circle, #0b5ed7 10%, transparent 20%);
  background-size: 30px 30px;
  opacity: 0.8;
  z-index: 1; /* 手前の文字より下にするモック用設定 */
}
.hvideo-css2-content-mock {
  position: relative;
  z-index: 2; /* 動画より手前に出す */
  color: #fff;
  text-align: center;
  text-shadow: 0 2px 4px rgba(0,0,0,0.5); /* 文字を読みやすくする影 */
}
.hvideo-css2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-css2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-css2-hl-comment { color: #6c757d; font-style: italic; }

positionプロパティの使い方を詳しく知りたい人は「【html&css】positionの使い方とabsolute・fixed・relativeの使い分け」を一読ください。

角丸や枠線・影のデザイン調整

埋め込んだ動画をサイトのデザインに馴染ませるため、角を丸くしたり、枠線やドロップシャドウを付けたりする装飾もCSSで行えます。

動画を装飾する場合は、動画タグにCSSクラスを当てるのではなく、動画を囲む親の枠を作り、親要素に対して角丸や影(overflow: hidden;とセット)を指定するのが安全でバグの出ない実装です。

🎨 角丸と影(シャドウ)の安全なデザイン調整

⭕️ 親コンテナに装飾をかけて安全に切り抜く

<!– HTML –>
<div class=”video-container”>
  <video src=”movie.mp4″ controls></video>
</div>

/* CSS */
.video-container {
  width: 100%;
  border-radius: 20px; /* ★ここで角丸にする */
  overflow: hidden; /* ★必須:はみ出た動画の角を切り落とす */
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); /* 影をつける */
  border: 4px solid #fff; /* 白い枠線 */
}

.video-container video {
  width: 100%;
  height: auto;
  display: block;
  /* videoタグ自体には装飾しないのが安全 */
}
HTMLコード表示
<div class="hvideo-css3-wrapper">
  
  <div class="hvideo-css3-demo-area">
    <div class="hvideo-css3-box">
      <div class="hvideo-css3-label">🎨 角丸と影(シャドウ)の安全なデザイン調整</div>
      
      <div class="hvideo-css3-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 親コンテナに装飾をかけて安全に切り抜く</p>
        
        <div class="hvideo-css3-mock-outer">
          <div class="hvideo-css3-mock-inner">
            <span style="font-size:30px; color:#fff;">▶</span>
          </div>
        </div>
      </div>

      <div class="hvideo-css3-code">
        <!-- HTML --><br>
        <span class="hvideo-css3-hl-blue"><div class="video-container"></span><br>
          <video src="movie.mp4" controls></video><br>
        <span class="hvideo-css3-hl-blue"></div></span><br><br>

        /* CSS */<br>
        <span class="hvideo-css3-hl-blue">.video-container</span> {<br>
          width: 100%;<br>
          <span class="hvideo-css3-hl-green">border-radius: 20px;</span>  /* ★ここで角丸にする */<br>
          <span class="hvideo-css3-hl-red">overflow: hidden;</span>     /* ★必須:はみ出た動画の角を切り落とす */<br>
          <span class="hvideo-css3-hl-green">box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);</span> /* 影をつける */<br>
          border: 4px solid #fff; /* 白い枠線 */<br>
        }<br><br>
        <span class="hvideo-css3-hl-blue">.video-container video</span> {<br>
          width: 100%;<br>
          height: auto;<br>
          display: block;<br>
          <span class="hvideo-css3-hl-comment">/* videoタグ自体には装飾しないのが安全 */</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-css3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-css3-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-css3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-css3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-css3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hvideo-css3-mock-outer {
  width: 80%;
  aspect-ratio: 16 / 9;
  border-radius: 20px; /* 角丸 */
  overflow: hidden;    /* はみ出しを隠す */
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); /* 影 */
  border: 4px solid #fff; /* 枠線 */
  background-color: #fff;
}
.hvideo-css3-mock-inner {
  width: 100%; height: 100%;
  background-color: #6c757d;
  display: flex;
  justify-content: center;
  align-items: center;
}
.hvideo-css3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-css3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css3-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-css3-hl-comment { color: #6c757d; font-style: italic; }

角丸や枠線・影のデザインを詳しく知りたい人は以下から一読ください。

コントロールバーの表示とダウンロード禁止設定

HTMLの<video>タグには、ユーザーが動画を操作する再生ボタンやシークバーを表示する機能が標準で備わっています。

動画をコンテンツとして見せる場合、背景動画として操作パネルを消したい場合、「動画の保存防止」、コントロールバー周りの設定方法を解説します。

コントロールバーの表示とダウンロード禁止設定
  • controls属性の表示・非表示と各種ボタン
  • サムネイル画像の設定とサイズ調整
  • 右クリック無効化とcontrolsListでのダウンロード禁止

controls属性の表示・非表示と各種ボタン

動画プレイヤーに標準の操作パネルを表示させるには、controls属性を使用します。

  • 表示する時
    <video controls>と書きます。
  • 非表示にする時
    controlsという単語自体をタグから削除します。
  • フルスクリーンの制御
    標準のコントロールバーから全画面ボタンだけを消す標準的なHTML属性は存在しません。
    独自のボタン構成にしたい場合は、標準コントロールを非表示にし、JavaScriptで独自の再生ボタンやシークバーを自作する必要があります。
🎛️ controls属性の表示と非表示

⭕️ 表示(controls を記述)

動画
🔊

⭕️ 非表示(属性ごと削除する)

動画 (操作バーなし)

※ controls=”false” は機能しないため注意

<!– ⭕️ 表示させたい場合 –>
<video src=”movie.mp4″ controls></video>

<!– ❌ 間違い:これでも表示されてしまう! –>
<video src=”movie.mp4″ controls=”false”></video>

<!– ⭕️ 非表示にしたい場合(単に書かない) –>
<video src=”movie.mp4″></video>
HTMLコード表示
<div class="hvideo-ctrl1-wrapper">
  
  <div class="hvideo-ctrl1-demo-area">
    <div class="hvideo-ctrl1-box">
      <div class="hvideo-ctrl1-label">🎛️ controls属性の表示と非表示</div>
      
      <div class="hvideo-ctrl1-visual">
        <div style="display:flex; flex-direction:column; gap:15px;">
          <div>
            <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 表示(controls を記述)</p>
            <div class="hvideo-ctrl1-mock-player">
              <div class="hvideo-ctrl1-mock-screen">動画</div>
              <div class="hvideo-ctrl1-mock-bar">
                <span>▶</span><span>🔊</span><span style="flex-grow:1; border-bottom:2px solid #ccc; margin:0 10px;"></span><span>⛶</span>
              </div>
            </div>
          </div>
          
          <div>
            <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⭕️ 非表示(属性ごと削除する)</p>
            <div class="hvideo-ctrl1-mock-player">
              <div class="hvideo-ctrl1-mock-screen">動画 (操作バーなし)</div>
            </div>
            <p style="font-size:11px; color:#666; margin-top:5px;">※ controls="false" は機能しないため注意</p>
          </div>
        </div>
      </div>

      <div class="hvideo-ctrl1-code">
        <!-- ⭕️ 表示させたい場合 --><br>
        <video src="movie.mp4" <span class="hvideo-ctrl1-hl-green">controls</span>></video><br><br>
        
        <!-- ❌ 間違い:これでも表示されてしまう! --><br>
        <video src="movie.mp4" <span class="hvideo-ctrl1-hl-red">controls="false"</span>></video><br><br>
        
        <!-- ⭕️ 非表示にしたい場合(単に書かない) --><br>
        <span class="hvideo-ctrl1-hl-blue"><video src="movie.mp4"></video></span>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-ctrl1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-ctrl1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-ctrl1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-ctrl1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-ctrl1-visual {
  background-color: #f1f3f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-ctrl1-mock-player {
  background-color: #212529;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #000;
}
.hvideo-ctrl1-mock-screen {
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 12px;
  background-image: repeating-linear-gradient(45deg, #343a40 10%, transparent 10%, transparent 20%, #343a40 20%, #343a40 30%);
}
.hvideo-ctrl1-mock-bar {
  background-color: #f8f9fa;
  padding: 5px 10px;
  display: flex;
  align-items: center;
  font-size: 14px;
  color: #333;
}
.hvideo-ctrl1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hvideo-ctrl1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-ctrl1-hl-red { color: #e06c75; font-weight: bold; }

サムネイル画像の設定とサイズ調整

動画が読み込まれる前や再生されるまでの間に表示しておく画像は、poster属性を使って指定します。

  • 元からサイズを合わせる
    用意するサムネイル画像は、動画本体と「同じアスペクト比(16:9など)」で作成してください。
  • CSSでカバーする
    ブラウザの仕様で画像がフィットしない場合、<video>タグに対してobject-fit: cover;を指定します。
    これにより、poster画像も動画領域に隙間なくトリミングされて配置されるようになります。
🖼️ サムネイル画像(poster)の設定

⭕️ poster属性とobject-fitで綺麗に表示

サムネイル画像 (poster.jpg)
<!– HTML –>
<video
  src=”movie.mp4″
  poster=”thumbnail.jpg” <!– ★サムネイルを指定 –>
  controls
  class=”cover-video”
></video>

/* CSS */
.cover-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover; /* ★黒帯を消し、隙間なく埋める */
}
HTMLコード表示
<div class="hvideo-ctrl2-wrapper">
  
  <div class="hvideo-ctrl2-demo-area">
    <div class="hvideo-ctrl2-box">
      <div class="hvideo-ctrl2-label">🖼️ サムネイル画像(poster)の設定</div>
      
      <div class="hvideo-ctrl2-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ poster属性とobject-fitで綺麗に表示</p>
        
        <div class="hvideo-ctrl2-mock-video">
          <div class="hvideo-ctrl2-mock-poster">
            サムネイル画像 (poster.jpg)
            <div class="hvideo-ctrl2-mock-playbtn">▶</div>
          </div>
        </div>
      </div>

      <div class="hvideo-ctrl2-code">
        <!-- HTML --><br>
        <video <br>
          src="movie.mp4" <br>
          <span class="hvideo-ctrl2-hl-green">poster="thumbnail.jpg"</span> <span class="hvideo-ctrl2-hl-comment"><!-- ★サムネイルを指定 --></span><br>
          controls <br>
          class="cover-video"<br>
        ></video><br><br>

        /* CSS */<br>
        <span class="hvideo-ctrl2-hl-blue">.cover-video</span> {<br>
          width: 100%;<br>
          aspect-ratio: 16 / 9;<br>
          <span class="hvideo-ctrl2-hl-red">object-fit: cover;</span> <span class="hvideo-ctrl2-hl-comment">/* ★黒帯を消し、隙間なく埋める */</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-ctrl2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-ctrl2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-ctrl2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-ctrl2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-ctrl2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-ctrl2-mock-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  background-color: #000;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.hvideo-ctrl2-mock-poster {
  width: 100%;
  height: 100%;
  background-color: #0d6efd;
  background-image: linear-gradient(135deg, #0b5ed7 25%, transparent 25%, transparent 50%, #0b5ed7 50%, #0b5ed7 75%, transparent 75%, transparent);
  background-size: 40px 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-weight: bold;
  font-size: 14px;
  text-shadow: 0 2px 4px rgba(0,0,0,0.5);
  position: relative;
}
.hvideo-ctrl2-mock-playbtn {
  position: absolute;
  background-color: rgba(0,0,0,0.6);
  width: 50px; height: 50px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  border: 2px solid #fff;
}
.hvideo-ctrl2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-ctrl2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-ctrl2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-ctrl2-hl-comment { color: #6c757d; font-style: italic; }

右クリック無効化とcontrolsListでのダウンロード禁止

「自社の動画を勝手に保存されたくない」という要望はWeb制作において多く、動画の保存を防ぐ対策が求められます。

HTMLとJavaScriptでできるダウンロードの防止は、あくまで「一般ユーザーのうっかり保存を防ぐ簡易的な対策」であると顧客に説明することが重要です。

その上で行うべき具体的な防御策は以下の2つです。

  1. controlsList="nodownload"
    コントロールバーのダウンロードボタンを非表示にする。
  2. oncontextmenu="return false;"
    動画上での右クリック(コンテキストメニュー)を禁止し、メニューからの保存を防ぐ。
🚫 ダウンロードボタンと右クリックの禁止

⚠️ 注意:拡張機能等による保存を完全に防ぐものではありません

1. ダウンロードボタンが消える
2. 右クリックしてもメニューが出ない
<video
  src=”movie.mp4″
  controls
  controlsList=”nodownload” <!– 1. DLボタンを非表示 –>
  oncontextmenu=”return false;” <!– 2. 右クリック禁止 –>
></video>
HTMLコード表示
<div class="hvideo-ctrl3-wrapper">
  
  <div class="hvideo-ctrl3-demo-area">
    <div class="hvideo-ctrl3-box">
      <div class="hvideo-ctrl3-label">🚫 ダウンロードボタンと右クリックの禁止</div>
      
      <div class="hvideo-ctrl3-visual">
        <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⚠️ 注意:拡張機能等による保存を完全に防ぐものではありません</p>
        
        <div class="hvideo-ctrl3-mock-video">
          <div style="font-size:12px; color:#fff; text-align:center;">
            1. ダウンロードボタンが消える<br>
            2. 右クリックしてもメニューが出ない
          </div>
        </div>
      </div>

      <div class="hvideo-ctrl3-code">
        <video <br>
          src="movie.mp4"<br>
          controls <br>
          <span class="hvideo-ctrl3-hl-green">controlsList="nodownload"</span> <span class="hvideo-ctrl3-hl-comment"><!-- 1. DLボタンを非表示 --></span><br>
          <span class="hvideo-ctrl3-hl-red">oncontextmenu="return false;"</span> <span class="hvideo-ctrl3-hl-comment"><!-- 2. 右クリック禁止 --></span><br>
        ></video>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-ctrl3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-ctrl3-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-ctrl3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-ctrl3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-ctrl3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-ctrl3-mock-video {
  width: 100%;
  height: 100px;
  background-color: #212529;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #000;
  cursor: not-allowed;
}
.hvideo-ctrl3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #dc3545;
}
.hvideo-ctrl3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-ctrl3-hl-comment { color: #6c757d; font-style: italic; }

JavaScriptで動画を操作する

HTMLの<video>タグに標準で備わっているcontrols属性は便利ですが、サイトのデザインに合わなかったり、機能が制限されていたりすることがあります。

実務で必須となるのが、JavaScriptを活用して、独自の動画プレイヤーを作成する技術です。

JavaScriptを使うことで、再生ボタンからシークバーまで、自由なデザインと仕様でコントロールできます。

ここでは、APIを利用した基本の操作、実務で直面する「シークバーの自作」や「イベント検知」を詳しく解説します。

JavaScriptで動画を操作する
  • 再生・一時停止と音量・速度変更
  • 再生時間の取得とシークバーの自作
  • イベント処理

再生・一時停止と音量・速度変更

カスタムプレイヤーを作るには、標準のコントロールバーを非表示にし、自前の再生ボタンや音量スライダーを用意することです。

JavaScriptから動画要素を取得し、play()pause()メソッドを呼び出すだけで操作が可能です。

また、音量や再生速度もプロパティの数値を書き換えるだけで変更できます。

  • 音量の指定
    volumeプロパティは0.0(無音)から1.0(最大)までの小数点で指定します。
    50%なら0.5です。
  • 再生速度の指定
    playbackRateプロパティを使用します。
    標準は1.0で、2倍速なら2.0、スローなら0.5になります。
▶️ カスタムコントロール(再生・音量・速度)
🎬
停止中
const video = document.querySelector(‘video’);

/* 💡 1. 再生と一時停止 */
btnPlay.addEventListener(‘click’, () => {
  video.play().catch(e => console.log(“再生ブロック”));
});
btnPause.addEventListener(‘click’, () => {
  video.pause();
});

/* 💡 2. 音量の変更(※ 0.0 〜 1.0 の間で指定する!) */
volumeSlider.addEventListener(‘input’, (e) => {
  video.volume = e.target.value; // 例: 0.5
});

/* 💡 3. 再生速度の変更 */
speedSelect.addEventListener(‘change’, (e) => {
  video.playbackRate = e.target.value; // 例: 2.0
});
HTMLコード表示
<div class="hvideo-js1-wrapper">
  
  <div class="hvideo-js1-demo-area">
    <div class="hvideo-js1-box">
      <div class="hvideo-js1-label">▶️ カスタムコントロール(再生・音量・速度)</div>
      
      <div class="hvideo-js1-visual">
        <div class="hvideo-js1-player-mock">
          <div class="hvideo-js1-screen-mock" id="mockScreen1">
            <span style="font-size:30px;">🎬</span>
            <div id="mockStatus1" style="font-size:12px; margin-top:5px;">停止中</div>
          </div>
          
          <div class="hvideo-js1-custom-controls">
            <button id="btnPlay1" class="hvideo-js1-btn">再生</button>
            <button id="btnPause1" class="hvideo-js1-btn">停止</button>
            
            <div class="hvideo-js1-control-group">
              <label>音量</label>
              <input type="range" id="volumeSlider" min="0" max="1" step="0.1" value="0.5">
            </div>
            
            <div class="hvideo-js1-control-group">
              <label>速度</label>
              <select id="speedSelect">
                <option value="0.5">0.5x</option>
                <option value="1.0" selected>1.0x</option>
                <option value="2.0">2.0x</option>
              </select>
            </div>
          </div>
        </div>
      </div>

      <div class="hvideo-js1-code">
        <span class="hvideo-js1-hl-blue">const</span> video = document.querySelector('video');<br><br>
        
        /* 💡 1. 再生と一時停止 */<br>
        btnPlay.addEventListener('click', () => {<br>
          video.<span class="hvideo-js1-hl-green">play()</span>.catch(e => console.log("再生ブロック"));<br>
        });<br>
        btnPause.addEventListener('click', () => {<br>
          video.<span class="hvideo-js1-hl-green">pause()</span>;<br>
        });<br><br>
        
        /* 💡 2. 音量の変更(※ 0.0 〜 1.0 の間で指定する!) */<br>
        volumeSlider.addEventListener('input', (e) => {<br>
          video.<span class="hvideo-js1-hl-red">volume</span> = e.target.value; <span class="hvideo-js1-hl-comment">// 例: 0.5</span><br>
        });<br><br>
        
        /* 💡 3. 再生速度の変更 */<br>
        speedSelect.addEventListener('change', (e) => {<br>
          video.<span class="hvideo-js1-hl-red">playbackRate</span> = e.target.value; <span class="hvideo-js1-hl-comment">// 例: 2.0</span><br>
        });
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-js1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-js1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-js1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 550px;
  border-radius: 4px;
}
.hvideo-js1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-js1-visual {
  background-color: #f1f3f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
}
.hvideo-js1-player-mock {
  border: 1px solid #ced4da;
  border-radius: 4px;
  overflow: hidden;
  background-color: #000;
}
.hvideo-js1-screen-mock {
  height: 120px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #fff;
  background-color: #212529;
}
.hvideo-js1-custom-controls {
  background-color: #f8f9fa;
  padding: 10px;
  display: flex;
  gap: 10px;
  align-items: center;
  border-top: 1px solid #dee2e6;
}
.hvideo-js1-btn {
  padding: 4px 10px;
  background-color: #0d6efd;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}
.hvideo-js1-btn:hover { background-color: #0b5ed7; }
.hvideo-js1-control-group {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: #333;
}
.hvideo-js1-control-group input[type="range"] { width: 60px; }
.hvideo-js1-control-group select { font-size: 11px; padding: 2px; }
.hvideo-js1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-js1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js1-hl-comment { color: #6c757d; font-style: italic; }
JavaScriptコード表示
setTimeout(() => {
  const btnPlay = document.getElementById('btnPlay1');
  const btnPause = document.getElementById('btnPause1');
  const mockStatus = document.getElementById('mockStatus1');
  const volumeSlider = document.getElementById('volumeSlider');
  const speedSelect = document.getElementById('speedSelect');

  if(btnPlay) {
    btnPlay.addEventListener('click', () => { mockStatus.textContent = "再生中..."; mockStatus.style.color = "#98c379"; });
    btnPause.addEventListener('click', () => { mockStatus.textContent = "停止中"; mockStatus.style.color = "#fff"; });
    volumeSlider.addEventListener('input', (e) => { mockStatus.textContent = `音量: ${e.target.value}`; mockStatus.style.color = "#fff"; });
    speedSelect.addEventListener('change', (e) => { mockStatus.textContent = `速度: ${e.target.value}x`; mockStatus.style.color = "#fff"; });
  }
}, 100);

再生時間の取得とシークバーの自作

カスタムプレイヤー実装において難易度が高いのが、プログレスバーの構築です。

これを実現するには、現在の再生時間と動画の全体の長さを取得し、パーセンテージを計算してバーの長さを更新する必要があります。

さらに、バーをクリックして好きな時間にジャンプさせる処理も実装します。

自作シークバーを実装する際は、「ユーザーがスライダーを掴んだ瞬間(mousedowninput)に動画を一度pause()して止め、スライダーから手を離した瞬間(changemouseup)に指定の秒数へジャンプさせてから再びplay()する」という処理の棲み分けが条件です。

🎚️ 再生時間の取得と自作シークバー

⭕️ currentTime と duration を使った連動

シークバー (input type=”range”)
00:15 01:00
/* 💡 1. ユーザーがバーを操作してジャンプ(シーク)する時 */
seekBar.addEventListener(‘input’, () => {
  // ★ドラッグ中は一時停止してカクつきを防ぐ
  video.pause();
  const seekTime = video.duration * (seekBar.value / 100);
  video.currentTime = seekTime;
});

seekBar.addEventListener(‘change’, () => {
  // ★手を離したら再生再開
  video.play();
});

/* 💡 2. 動画の再生に合わせてバーを動かす(後述のイベント内で実行) */
const percent = (video.currentTime / video.duration) * 100;
seekBar.value = percent;
HTMLコード表示
<div class="hvideo-js2-wrapper">
  <div class="hvideo-js2-demo-area">
    <div class="hvideo-js2-box">
      <div class="hvideo-js2-label">🎚️ 再生時間の取得と自作シークバー</div>
      
      <div class="hvideo-js2-visual">
        <p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ currentTime と duration を使った連動</p>
        
        <div class="hvideo-js2-seek-mock">
          <div style="font-size:11px; color:#666; margin-bottom:5px;">シークバー (input type="range")</div>
          <div style="display:flex; align-items:center; gap:10px;">
            <span id="timeCurrent" style="font-size:11px; font-family:monospace;">00:15</span>
            <input type="range" id="seekBar" min="0" max="100" value="25" style="flex-grow:1;">
            <span id="timeDuration" style="font-size:11px; font-family:monospace;">01:00</span>
          </div>
        </div>
      </div>

      <div class="hvideo-js2-code">
        /* 💡 1. ユーザーがバーを操作してジャンプ(シーク)する時 */<br>
        seekBar.addEventListener(<span class="hvideo-js2-hl-red">'input'</span>, () => {<br>
          <span class="hvideo-js2-hl-comment">// ★ドラッグ中は一時停止してカクつきを防ぐ</span><br>
          video.pause(); <br>
          <span class="hvideo-js2-hl-blue">const</span> seekTime = video.<span class="hvideo-js2-hl-green">duration</span> * (seekBar.value / 100);<br>
          video.<span class="hvideo-js2-hl-green">currentTime</span> = seekTime;<br>
        });<br><br>
        
        seekBar.addEventListener(<span class="hvideo-js2-hl-red">'change'</span>, () => {<br>
          <span class="hvideo-js2-hl-comment">// ★手を離したら再生再開</span><br>
          video.play();<br>
        });<br><br>

        /* 💡 2. 動画の再生に合わせてバーを動かす(後述のイベント内で実行) */<br>
        <span class="hvideo-js2-hl-blue">const</span> percent = (video.<span class="hvideo-js2-hl-green">currentTime</span> / video.<span class="hvideo-js2-hl-green">duration</span>) * 100;<br>
        seekBar.value = percent;
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-js2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-js2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-js2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-js2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-js2-visual {
  background-color: #f1f3f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-js2-seek-mock {
  background-color: #fff;
  padding: 15px;
  border-radius: 4px;
  border: 1px solid #ced4da;
}
.hvideo-js2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-js2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js2-hl-comment { color: #6c757d; font-style: italic; }

イベント処理

JavaScriptで動画を制御するには、動画が「今どんな状態なのか」を監視する各種イベントを使いこなす必要があります。

カスタムプレイヤー構築で多用する3つのイベントを覚えましょう。

  1. timeupdate
    動画の再生位置が変わるたびに連続して発生します。
    シークバーを進める処理はこの中で書きます。
  2. ended
    動画が最後まで再生され終わった瞬間に発生します。
    リプレイボタンを表示したり、次の動画へ遷移させたりする処理に使います。
  3. play/pause
    再生・一時停止が行われた瞬間に発生します。
    再生ボタンのアイコンを「⏸️」や「▶️」に切り替える同期処理に使います。
📡 必須となる三大イベント処理

⭕️ onloadではなく、動画専用のイベントを検知する

  • loadedmetadata:読み込み完了時
  • timeupdate:再生中に毎秒数回発火
  • ended:動画が最後まで終わった時
<!– ❌ 間違い:videoにonloadは使えない –>
<video src=”movie.mp4″ onload=”init()”></video>

/* 💡 1. 読み込み完了(全体の長さを取得可能になる) */
video.addEventListener(‘loadedmetadata’, () => {
  // ここで初めて video.duration が正確に取得できる
  console.log(“全体の長さ: ” + video.duration);
});

/* 💡 2. 再生位置の更新(シークバーを進める処理) */
video.addEventListener(‘timeupdate’, () => {
  // 再生中は1秒間に数回ここが実行される
  updateSeekBar(video.currentTime);
});

/* 💡 3. 再生終了(リプレイ画面を出す等) */
video.addEventListener(‘ended’, () => {
  showReplayButton();
});
HTMLコード表示
<div class="hvideo-js3-wrapper">
  
  <div class="hvideo-js3-demo-area">
    <div class="hvideo-js3-box">
      <div class="hvideo-js3-label">📡 必須となる三大イベント処理</div>
      
      <div class="hvideo-js3-visual">
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ onloadではなく、動画専用のイベントを検知する</p>
        
        <div class="hvideo-js3-event-mock">
          <ul style="margin:0; padding-left:15px; font-size:12px; color:#333; line-height:1.8;">
            <li>✅ <strong style="color:#0d6efd">loadedmetadata</strong>:読み込み完了時</li>
            <li>✅ <strong style="color:#0d6efd">timeupdate</strong>:再生中に毎秒数回発火</li>
            <li>✅ <strong style="color:#0d6efd">ended</strong>:動画が最後まで終わった時</li>
          </ul>
        </div>
      </div>

      <div class="hvideo-js3-code">
        <!-- ❌ 間違い:videoにonloadは使えない --><br>
        <video src="movie.mp4" <span class="hvideo-js3-hl-red">onload="init()"</span>></video><br><br>

        /* 💡 1. 読み込み完了(全体の長さを取得可能になる) */<br>
        video.addEventListener(<span class="hvideo-js3-hl-green">'loadedmetadata'</span>, () => {<br>
          <span class="hvideo-js3-hl-comment">// ここで初めて video.duration が正確に取得できる</span><br>
          console.log("全体の長さ: " + video.duration);<br>
        });<br><br>

        /* 💡 2. 再生位置の更新(シークバーを進める処理) */<br>
        video.addEventListener(<span class="hvideo-js3-hl-green">'timeupdate'</span>, () => {<br>
          <span class="hvideo-js3-hl-comment">// 再生中は1秒間に数回ここが実行される</span><br>
          updateSeekBar(video.currentTime);<br>
        });<br><br>

        /* 💡 3. 再生終了(リプレイ画面を出す等) */<br>
        video.addEventListener(<span class="hvideo-js3-hl-green">'ended'</span>, () => {<br>
          showReplayButton();<br>
        });
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-js3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-js3-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-js3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-js3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-js3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-js3-event-mock {
  background-color: #fff;
  padding: 15px;
  border-radius: 4px;
  border: 1px solid #ced4da;
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
}
.hvideo-js3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-js3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js3-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js3-hl-comment { color: #6c757d; font-style: italic; }

動画が再生されない:エラー解決と読み込み最適化

動画をWebサイトに埋め込んだものの再生されないトラブルは、Web制作で多い問い合わせの一つです。

特に「PCのテスト環境では動くのに、再生されないスマホの環境がある」「画面が真っ暗な状態になる」といった問題は、原因の特定が難しいです。

ここでは、「ファイルが見つからない・形式がおかしい」エラーの解決策、サイトの表示速度を落とさない読み込み最適化(Lazy load)を解説します。

動画が再生されない:エラー解決と読み込み最適化
  • 「video file not found」やエンコードエラーの対処
  • preload属性を使った読み込み最適化

「video file not found」やエンコードエラーの対処

コンソール画面やプレイヤー上に「video file not found」と表示される場合、基本的には「動画のパス(URL)が間違っている」ことが原因です。

解決策としては、相対パスの大文字・小文字の打ち間違いやローカルパス(C:\Users\...)を指定していないかを確認するのがよいです。

  • エンコードの確認
    Web用に動画を用意する際は、書き出し設定で「コーデック:H.264」「フォーマット:MP4」を選択してください。
  • MIMEタイプの明示
    HTML側でも<source>タグのtype属性を使ってファイル形式をブラウザに明示することで、再生エラーを減らし、読み込みの無駄を省けます。
🚨 動画エラーを防ぐパスとtypeの指定

❌ 再生されない・エラーになる原因

  • PCのローカルフォルダの絶対パスを書いている
  • コーデックが「H.264」以外(H.265等)になっている
  • 大文字・小文字が間違っている(Movie.MP4 など)
<!– ❌ 悪い例1:自分のパソコンでしか見れないパス –>
<video src=”C:\Users\Desktop\video.mp4“></video>

<!– ❌ 悪い例2:拡張子を無理やり書き換えただけのファイル –>
<video src=”movie_h265.mp4“></video>

<!– ⭕️ 良い例:正しい相対パスと、type属性による明示 –>
<video controls poster=”img/thumb.jpg”>
  <!– ★ H.264コーデックでエンコードした動画を指定 –>
  <source src=”./assets/video/movie.mp4″ type=”video/mp4″>
  <p>お使いのブラウザは動画に対応していません。</p>
</video>
HTMLコード表示
<div class="hvideo-err1-wrapper">
  
  <div class="hvideo-err1-demo-area">
    <div class="hvideo-err1-box">
      <div class="hvideo-err1-label">🚨 動画エラーを防ぐパスとtypeの指定</div>
      
      <div class="hvideo-err1-visual">
        <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ 再生されない・エラーになる原因</p>
        <ul style="font-size:12px; color:#333; margin:0 0 15px 15px; padding:0; line-height:1.6;">
          <li>PCのローカルフォルダの絶対パスを書いている</li>
          <li>コーデックが「H.264」以外(H.265等)になっている</li>
          <li>大文字・小文字が間違っている(Movie.MP4 など)</li>
        </ul>
      </div>

      <div class="hvideo-err1-code">
        <!-- ❌ 悪い例1:自分のパソコンでしか見れないパス --><br>
        <video src="<span class="hvideo-err1-hl-red">C:\Users\Desktop\video.mp4</span>"></video><br><br>

        <!-- ❌ 悪い例2:拡張子を無理やり書き換えただけのファイル --><br>
        <video src="<span class="hvideo-err1-hl-red">movie_h265.mp4</span>"></video><br><br>

        <!-- ⭕️ 良い例:正しい相対パスと、type属性による明示 --><br>
        <span class="hvideo-err1-hl-blue"><video controls poster="img/thumb.jpg"></span><br>
          <span class="hvideo-err1-hl-comment"><!-- ★ H.264コーデックでエンコードした動画を指定 --></span><br>
          <span class="hvideo-err1-hl-green"><source src="./assets/video/movie.mp4" type="video/mp4"></span><br>
          <p>お使いのブラウザは動画に対応していません。</p><br>
        <span class="hvideo-err1-hl-blue"></video></span>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-err1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-err1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-err1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 550px;
  border-radius: 4px;
}
.hvideo-err1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-err1-visual {
  background-color: #f8d7da;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #f5c2c7;
}
.hvideo-err1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-err1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-err1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-err1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-err1-hl-comment { color: #6c757d; font-style: italic; }

preload属性を使った読み込み最適化

動画はデータ容量が大きいため、ページ内に複数配置するとサイトの読み込み速度が激減します。

そこで必須となるのが、「preload」の適切な設定と、画面に表示されるまで動画の読み込みを遅らせる遅延読み込みの技術です。

  • 基本のブロック
    ファーストビューにない動画は、preload="none"を指定して、ユーザーが再生ボタンを押すまでダウンロードを完全に防ぎます。
    (※metadataを指定すると動画の長さ情報だけを先に取得します。)
  • 最適化(Lazy load)
    スクロールして自動再生させたい背景動画などは、HTMLにはURLを書かず、JavaScriptのIntersection Observerを使って「画面に動画が見えた瞬間に動画のURLをセットして読み込む」という実装を行います。
⚡ 動画の遅延読み込み(Lazy Load)

⭕️ スクロールして枠内に入ると読み込み開始

↓ 下へスクロールしてください
待機中 (通信ゼロ)
<!– HTML:最初は src を書かず data-src に隠しておく –>
<video preload=”none” class=”lazy-video”
  data-src=”heavy-movie.mp4″
  muted playsinline loop>
</video>

/* 💡 JavaScript:画面に入ったら src を入れて再生 */
const lazyVideos = document.querySelectorAll(‘.lazy-video’);

const videoObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const video = entry.target;
      // data-src のURLを本物の src に移す
      video.src = video.dataset.src;
      video.play(); // 読み込み後に再生
      videoObserver.unobserve(video); // 監視終了
    }
  });
});

lazyVideos.forEach(v => videoObserver.observe(v));
HTMLコード表示
<div class="hvideo-err2-wrapper">
  
  <div class="hvideo-err2-demo-area">
    <div class="hvideo-err2-box">
      <div class="hvideo-err2-label">⚡ 動画の遅延読み込み(Lazy Load)</div>
      
      <div class="hvideo-err2-visual">
        <p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ スクロールして枠内に入ると読み込み開始</p>
        
        <div id="lazyScrollArea" class="hvideo-err2-scroll-area">
          <div style="height:150px; padding:20px; background:#f8f9fa; font-size:12px;">↓ 下へスクロールしてください</div>
          
          <div class="hvideo-err2-mock-video-container">
            <div id="lazyVideoMock" class="hvideo-err2-mock-video">
              <span id="lazyStatus">待機中 (通信ゼロ)</span>
            </div>
          </div>
          
          <div style="height:100px; background:#f8f9fa;"></div>
        </div>
      </div>

      <div class="hvideo-err2-code">
        <!-- HTML:最初は src を書かず data-src に隠しておく --><br>
        <video <span class="hvideo-err2-hl-red">preload="none"</span> class="lazy-video"<br>
          <span class="hvideo-err2-hl-green">data-src="heavy-movie.mp4"</span><br>
          muted playsinline loop><br>
        </video><br><br>

        /* 💡 JavaScript:画面に入ったら src を入れて再生 */<br>
        <span class="hvideo-err2-hl-blue">const</span> lazyVideos = document.querySelectorAll('.lazy-video');<br><br>
        <span class="hvideo-err2-hl-blue">const</span> videoObserver = <span class="hvideo-err2-hl-blue">new</span> IntersectionObserver((entries) => {<br>
          entries.forEach(entry => {<br>
            <span class="hvideo-err2-hl-blue">if</span> (entry.isIntersecting) {<br>
              <span class="hvideo-err2-hl-blue">const</span> video = entry.target;<br>
              <span class="hvideo-err2-hl-comment">// data-src のURLを本物の src に移す</span><br>
              video.<span class="hvideo-err2-hl-green">src</span> = video.dataset.src;<br>
              video.play(); <span class="hvideo-err2-hl-comment">// 読み込み後に再生</span><br>
              videoObserver.unobserve(video); <span class="hvideo-err2-hl-comment">// 監視終了</span><br>
            }<br>
          });<br>
        });<br><br>
        lazyVideos.forEach(v => videoObserver.observe(v));
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-err2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-err2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-err2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 550px;
  border-radius: 4px;
}
.hvideo-err2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-err2-visual {
  background-color: #fff;
  padding: 0;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  overflow: hidden;
}
.hvideo-err2-scroll-area {
  height: 180px;
  overflow-y: scroll;
  position: relative;
}
.hvideo-err2-mock-video-container {
  padding: 20px;
  background-color: #e9ecef;
}
.hvideo-err2-mock-video {
  width: 100%;
  height: 120px;
  background-color: #6c757d;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 12px;
  font-weight: bold;
  transition: background-color 0.5s;
}
.hvideo-err2-mock-video.is-loaded {
  background-color: #198754;
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.1) 75%, rgba(255,255,255,0.1)), repeating-linear-gradient(45deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.1) 75%, rgba(255,255,255,0.1));
  background-size: 20px 20px;
}
.hvideo-err2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hvideo-err2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-err2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-err2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-err2-hl-comment { color: #6c757d; font-style: italic; }
JavaScriptコード表示
setTimeout(() => {
  const scrollArea = document.getElementById('lazyScrollArea');
  const mockVideo = document.getElementById('lazyVideoMock');
  const statusText = document.getElementById('lazyStatus');
  
  if(!scrollArea || !mockVideo) return;

  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        // 画面に入った瞬間にクラスを付与して状態を変更
        mockVideo.classList.add('is-loaded');
        statusText.innerHTML = "読み込み開始!<br>▶ 再生中...";
        observer.unobserve(mockVideo);
      }
    });
  }, {
    root: scrollArea, // スクロールエリア内での交差を検知
    threshold: 0.5    // 半分見えたら発火
  });

  observer.observe(mockVideo);
}, 100);

YouTubeやVimeoを埋め込む場合

自社サーバーに動画をアップロードして表示する標準的な方法を解説してきましたが、実務では「YouTubeの動画をサイトに載せたい」というケースも多いです。

YouTubeやVimeoなどの外部プラットフォームの動画を埋め込む場合、<video>タグは使用できません。

代わりに<iframe>タグを使用して、外部の動画ソースを読み込みます。

ここでは、<video>タグとの使い分け、スマホ画面に合わせて伸縮させるレスポンシブ対応を解説します。

YouTubeやVimeoを埋め込む場合
  • videoタグとiframeタグの違いと使い分け
  • YouTube動画の自動再生やレスポンシブ化

videoタグとiframeタグの違いと使い分け

自社サーバーの動画ファイルを直接読み込む<video>タグに対し、別のサイトのプレイヤーごと自分のサイトに表示させるのが<iframe>タグです。

実務では、以下の基準でタグを使い分けます。

  • <video>
    数秒〜数十秒の短い背景動画、デザインに溶け込ませたい自作プレイヤー、外部のロゴを出したくない場合。
  • <iframe>
    数分以上の長い動画、サーバーのデータ通信量を節約したい場合、YouTube側のストリーミング配信システムを利用して再生させたい場合。
🔗 YouTube動画の正しい埋め込み方

❌ videoタグにYouTubeのURLを入れるのはNG

⭕️ 公式の「埋め込む」からiframeコードを取得する

YouTube Player
<!– ❌ ありがちな間違い:絶対に再生されません –>
<video src=”https://www.youtube.com/watch?v=xxxxx”></video>

<!– ⭕️ 正解:iframeタグを使う(YouTubeの共有ボタンから取得) –>
<iframe
  width=”560″
  height=”315″
  src=”https://www.youtube.com/embed/xxxxx”
  title=”YouTube video player”
  frameborder=”0″
  allow=”accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture”
  allowfullscreen
></iframe>
HTMLコード表示
<div class="hvideo-iframe1-wrapper">
  <div class="hvideo-iframe1-demo-area">
    <div class="hvideo-iframe1-box">
      <div class="hvideo-iframe1-label">🔗 YouTube動画の正しい埋め込み方</div>
      
      <div class="hvideo-iframe1-visual">
        <p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ videoタグにYouTubeのURLを入れるのはNG</p>
        <p style="font-size:12px; color:#198754; font-weight:bold; margin:15px 0 5px 0;">⭕️ 公式の「埋め込む」からiframeコードを取得する</p>
        
        <div class="hvideo-iframe1-mock-youtube">
          <div class="hvideo-iframe1-mock-screen">
            <span style="color:red; font-size:30px;">▶</span>
            <span style="color:#fff; font-size:14px; margin-left:10px;">YouTube Player</span>
          </div>
        </div>
      </div>

      <div class="hvideo-iframe1-code">
        <!-- ❌ ありがちな間違い:絶対に再生されません --><br>
        <span class="hvideo-iframe1-hl-red"><video src="https://www.youtube.com/watch?v=xxxxx"></video></span><br><br>

        <!-- ⭕️ 正解:iframeタグを使う(YouTubeの共有ボタンから取得) --><br>
        <span class="hvideo-iframe1-hl-blue"><iframe</span> <br>
          width="560" <br>
          height="315" <br>
          <span class="hvideo-iframe1-hl-green">src="https://www.youtube.com/embed/xxxxx"</span> <br>
          title="YouTube video player" <br>
          frameborder="0" <br>
          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"<br>
          allowfullscreen<br>
        <span class="hvideo-iframe1-hl-blue">></iframe></span>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-iframe1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-iframe1-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-iframe1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-iframe1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-iframe1-visual {
  background-color: #f1f3f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-iframe1-mock-youtube {
  background-color: #000;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.hvideo-iframe1-mock-screen {
  height: 120px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.hvideo-iframe1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hvideo-iframe1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-iframe1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-iframe1-hl-red { color: #e06c75; font-weight: bold; }

iframeタグの使い方を詳しく知りたい人は「【HTML】iframeタグの使い方:YouTube・グーグルマップ等埋め込みとサイズ調整」を一読ください。

YouTube動画の自動再生やレスポンシブ化

YouTubeの共有コードを貼り付けるとサイズが固定(width="560" height="315"など)されてしまうため、スマホで見ると画面からはみ出します。

また、動画を自動再生させるには、少し特殊なURLパラメーターの追加が必要です。

  • 自動再生
    URLの末尾に、自動再生のautoplay=1、ミュートのmute=1をセットにして?autoplay=1&mute=1と記述します(パラメーターがすでにある場合は&で繋ぎます)。
  • レスポンシブ
    CSSではiframeに対してwidth: 100%;に加え、aspect-ratio: 16 / 9;を指定するだけで縦横比を維持できます。
📱 レスポンシブ化と自動再生パラメーター

⭕️ アスペクト比を維持して伸縮するiframe

width: 100% / aspect-ratio: 16/9
<!– HTML –>
<iframe
  class=”youtube-responsive”
  <!– 💡 URLの末尾に「自動再生&無音」のパラメーターを付ける –>
  src=”https://www.youtube.com/embed/xxxxx?autoplay=1&mute=1
  frameborder=”0″ allowfullscreen>
</iframe>

/* CSS */
.youtube-responsive {
  width: 100%;
  /* height: auto; は効かないので絶対に書かない */
  aspect-ratio: 16 / 9; /* ★これで縦横比を16:9に固定して伸縮 */
  border: none;
}
HTMLコード表示
<div class="hvideo-iframe2-wrapper">
  <div class="hvideo-iframe2-demo-area">
    <div class="hvideo-iframe2-box">
      <div class="hvideo-iframe2-label">📱 レスポンシブ化と自動再生パラメーター</div>
      
      <div class="hvideo-iframe2-visual">
        <p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ アスペクト比を維持して伸縮するiframe</p>
        
        <div class="hvideo-iframe2-mock-container">
          <div class="hvideo-iframe2-mock-responsive">
            <span style="font-size:24px; color:#fff;">▶</span>
            <div style="font-size:11px; color:#ccc; margin-top:5px;">width: 100% / aspect-ratio: 16/9</div>
          </div>
        </div>
      </div>

      <div class="hvideo-iframe2-code">
        <!-- HTML --><br>
        <iframe <br>
          class="youtube-responsive"<br>
          <span class="hvideo-iframe2-hl-comment"><!-- 💡 URLの末尾に「自動再生&無音」のパラメーターを付ける --></span><br>
          src="https://www.youtube.com/embed/xxxxx<span class="hvideo-iframe2-hl-red">?autoplay=1&mute=1</span>" <br>
          frameborder="0" allowfullscreen><br>
        </iframe><br><br>

        /* CSS */<br>
        <span class="hvideo-iframe2-hl-blue">.youtube-responsive</span> {<br>
          <span class="hvideo-iframe2-hl-green">width: 100%;</span><br>
          <span class="hvideo-iframe2-hl-comment">/* height: auto; は効かないので絶対に書かない */</span><br>
          <span class="hvideo-iframe2-hl-green">aspect-ratio: 16 / 9;</span> <span class="hvideo-iframe2-hl-comment">/* ★これで縦横比を16:9に固定して伸縮 */</span><br>
          border: none;<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.hvideo-iframe2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hvideo-iframe2-demo-area {
  display: flex;
  justify-content: center;
}
.hvideo-iframe2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hvideo-iframe2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}
.hvideo-iframe2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hvideo-iframe2-mock-container {
  width: 100%; /* 親要素の幅に合わせて伸縮 */
  border: 2px solid #0d6efd;
}
.hvideo-iframe2-mock-responsive {
  width: 100%;
  aspect-ratio: 16 / 9; /* これがレスポンシブの鍵 */
  background-color: #212529;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 10%, transparent 10%, transparent 20%, rgba(255,255,255,0.05) 20%, rgba(255,255,255,0.05) 30%);
}
.hvideo-iframe2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hvideo-iframe2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-iframe2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-iframe2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-iframe2-hl-comment { color: #6c757d; font-style: italic; }

要素に対するレスポンシブ対応について詳しく知りたい人は「【CSS】レスポンシブデザイン対応の基本:メディアクエリの書き方とパーツ別サンプル集」を一読ください。

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • 基本記述
    動画の埋め込みには<video>タグを使用し、複数形式の指定やエラー表示には<source>タグを用いる。
  • 推奨フォーマット
    全ブラウザ対応の「MP4(H.264コーデック)」を必須とし、軽量化目的で「WebM」を優先して指定する。
  • スマホの自動再生
    スマートフォン環境で動画を自動再生・ループさせるには、autoplay muted playsinline loopの4属性指定が必須。
  • レスポンシブ対応
    CSSでwidth: 100%; height: auto;を指定し、動画の元のアスペクト比(縦横比)を維持して伸縮させる。
  • 背景動画化
    動画を画面いっぱいの背景にする場合は、object-fit: cover;を使用して隙間なくトリミングする。
  • UI表示
    controls属性の有無で標準コントローラーの表示・非表示を切り替える。
    サムネイル画像はposter属性で指定する。
  • 保存対策
    controlsList="nodownload"と右クリック禁止(oncontextmenu="return false;")を組み合わせることで簡易的なダウンロード防止策となる。
  • JavaScript制御
    play()pause()メソッドで直接操作し、timeupdateendedなどの動画専用イベントで再生状況を監視する。
  • 読み込み最適化
    画面外の動画はpreload="none"の指定やIntersection Observerを用いた遅延読み込み(Lazy Load)により通信量を抑える。
  • 外部動画の埋め込み
    YouTubeやVimeoなどの動画を使用する場合は、<video>タグではなく提供された<iframe>タグを使用する。

よくある質問(FAQ)

HTMLで動画を埋め込むにはどのタグを使えばいいですか?

HTML5から導入された<video>タグを使用します。

簡単な書き方は<video src="movie.mp4" controls></video>のように直接ファイルパスを指定する方法です。

実務ではブラウザの互換性を考慮し、<video>タグの中に<source>タグを配置して複数の動画形式(MP4やWebM)を指定するのが一般的です。

スマホ(iPhone等)で動画が自動再生されないのはなぜですか?

モバイル端末のブラウザは、ユーザーの通信量保護や突然の音の発生を防ぐため、「無音設定」になっていない動画の自動再生をブロックする仕様になっています。

スマホでも自動再生させるには、<video>タグにautoplay(自動再生)に加えて、muted(無音化)とplaysinline(iPhoneでの全画面化を防ぐ)属性をセットで記述する必要があります。

HTMLのvideoタグで使える動画の形式(拡張子)は何ですか?

すべてのブラウザで再生できる標準フォーマットは 「MP4(コーデックはH.264)」 です。

また、データ容量が軽く高速に表示できる 「WebM」 形式もGoogleを中心に推奨されています。

一方で、iPhoneで撮影したままの「MOV」形式、古い「AVI」「WMV」などはWeb標準ではないため、ブラウザによっては再生できず画面が真っ暗になります。

MP4等に変換(エンコード)して使用してください。

動画をスマホの画面幅に合わせてレスポンシブにするにはどうすればいいですか?

CSSを使って、動画が親要素(画面枠)からはみ出さないように設定します。

<video>タグに対してwidth: 100%;height: auto;を指定するのが確実な方法です。

高さをautoにすることで、ブラウザが動画の元の縦横比を自動計算するため、動画が縦に伸びたり横に潰れたりすることなく伸縮します。

YouTubeの動画をサイトに埋め込むのに<video>タグは使えますか?

いいえ、使えません。

<video>タグは、自社のサーバー等にアップロードした直接の動画ファイル(.mp4など)を読み込む専用タグです。

YouTubeやVimeoといった外部プラットフォームの動画を表示したい場合は、YouTubeの共有メニューから取得できる<iframe>タグをHTMLに貼り付けて使用する必要があります。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次