【Web開発応用】動画再生4つの手法と使い分け

はじめに

最近、余り記事を書いてないですが、ゲーム開発は継続してます。

EDを作ったらゲームを公開できるかというと、そんなわけでもなく、まだまだやる事が沢山あったり、

  • i18n(多言語対応)実装
  • localStorageでゲーム設定&履歴を保存

は既に終わったものの、まだまだ実装したい機能が多数あり、その作業に追われています。

公に公表できない情報についての会話が多くなってしまって、以前のように対話ログを気軽に投稿も出来なくなってます。

基本的に、今やってる事で困った事を、そのまま記事ネタにしてるので、どうしてもリアルの実装の現場の情報が漏洩してるのが現状です。

無料で公開する予定ですし、フルオープンにして、オープンソース的に共同開発者を募集するのも悪くない選択だとも思っています。

公開するとなると、特にスマホに対応させる為には、見直すことが沢山あり、本当に作品を世に出すのは難しい事だと最近良く感じています。

適当に作って公開してる人も多いので、そこまで完璧主義になって作らなくても良いとは思います…。

前置きが長くなりましたが、今回のネタは、メインゲームの実装が一通り落ち着いて、当初アイデアの一つとして考えていた、ゲームクリア時に 動画の演出を作るにあたり、どんな方法があるのかの実験といつも通り、備忘録メモも兼ねて公開してみます。

情報がゲーム開発や、WEB制作の参考になれば幸いです。

これからやる内容を確認

目的:

  • 動画再生のさまざまな方法を比較・実装して紹介する

対象:

  • JavaScriptベースのWebアプリ開発者やゲーム開発者

環境:

  • ローカル開発サーバーあり(Live Server)
  • 動画ファイル形式:MP4 or WebM

もし記事を見て興味を持ちコードを書く人の為に、動画素材を置いておきます。

■ 制作に使ったツール

  • FramePack-eichi
  • Stable Diffusion checkpoint
  • novaAnimeXL_ilV90

■ サンプル動画(Download)

ダウンロードして使ってもらって構いません。

web-video-sample-01.mp4


1. はじめに: video タグだけじゃない再生手法

動画をWeb上で再生する――その第一歩として、多くの人がまず使うのが<video>タグです。
HTML5で標準化されて以来、<video>は非常に便利で、シンプルな構文で再生、停止、ループ、コントロールUIまで提供してくれます。

<video src="sample.mp4" controls autoplay loop></video>

たったこれだけで動画をページに埋め込めるのですから、まさに魔法のような存在です。

しかし、Webアプリやゲーム開発、UI演出、PWAやインタラクティブなアニメーションを作ろうとすると、
「<video>では物足りない」
という瞬間が訪れます。

🔍 たとえば、こんなケース

  • 再生タイミングを完全にJS側で制御したい
  • 背景として動画をCanvas描画したい
  • フレーム単位での操作(早送り・巻き戻し・ポーズ処理)をしたい
  • 複数の短尺動画を合成/ループで切り替えたい
  • <video>だと表示や音がもたつく(モバイル制限)

こうしたニーズに対応するために、本記事では
「HTML5の標準を超えた、JavaScriptによる動的な動画再生手法」
をいくつか紹介し、比較していきます。

制御力、応答性、自由度を求める開発者のための「動画再生ハック」 を、
一緒に体験していきましょう。

2. 再生方法一覧(概要比較表つき)

動画再生と一口に言っても、その手法は多岐にわたります。

ここでは代表的な方法を5つに分け、それぞれの特徴をざっくり比較してみます。

📊 概要比較表

再生方法 実装難度 カスタマイズ性 対応デバイス 特徴・用途
<video> タグ ★☆☆☆☆ ★☆☆☆☆ ◎ 全般対応 最も簡単。再生/停止/ループ等がすぐ使える。
JS制御 + <video> ★★☆☆☆ ★★☆☆☆ ◎ 全般対応 イベントや再生位置制御など、JSで操作可能。
<canvas> に描画 ★★★★☆ ★★★★★ ◯ 限定的 完全にJS制御可。ゲームやUI合成に使える。
WebGL/Three.js + Video ★★★★★ ★★★★★ △ 高性能機種 3Dオブジェクトに貼れる。背景演出や特撮系に◎。
FFmpeg.wasm(再生風) ★★★★★ ★★★★★ △ ブラウザ依存 動画を読み解いて画像列として制御する。実験的。

💡 用途で選ぶと?

  • 普通の動画プレイヤー → videoタグ
  • 細かくコントロールしたい → JSで制御
  • ゲーム/アニメUIで使いたい → Canvas描画
  • 3D表現を入れたい → WebGL & Three.js
  • カットシーン的に演出したい → Canvas + 画像列再生

次は、それぞれの手法を実装サンプル付きで解説していきます。

✅ 「あなたの目的に一番合う再生方法はどれか?」を意識して、読み進めてみてください。

3. <video>タグ+JavaScriptの再生制御

HTMLの<video>タグは、最も手軽に動画を再生できる手段です。

ただし、JavaScriptと組み合わせることで、より細やかな操作や演出が可能になります。

🔰 基本構文

<video id="myVideo" src="movie.mp4" width="640" controls></video>

<script>
  const video = document.getElementById("myVideo");
  video.play();        // 再生
  video.pause();       // 一時停止
  video.currentTime = 10; // 10秒地点へ移動
  video.volume = 0.5;  // 音量50%
</script>

サンプル

🧩 よく使う制御API一覧

メソッド・プロパティ 内容
.play() 再生
.pause() 一時停止
.currentTime 現在の再生位置(秒)
.duration 動画の長さ(秒)
.volume 音量(0.0〜1.0)
.muted ミュート(true/false)
.loop ループ再生するか(true/false)

🎬 カスタム再生ボタンの例

<button onclick="video.play()">▶ 再生</button>
<button onclick="video.pause()">⏸ 一時停止</button>
<button onclick="video.currentTime = 0">⏮ 最初に戻る</button>

🧠 イベント連携で演出も可能!

video.addEventListener("ended", () => {
  alert("動画が終わりました!");
});

✅ 利用場面とポイント

  • 操作UIを自作したいとき(controls を使わず自前で実装)
  • スクリプトで再生位置やタイミングを制御したいとき
  • BGM・ボイス・演出との同期再生をしたいとき

👀 これだけでも十分に高機能ですが、
次のセクションでは、Canvasへの描画による完全制御の世界を覗いてみましょう。


user icon

[media pointer=“file-service://file-6WQeTSB1XCzJSeqdvxphrq”] 以下のエラーが出ますが、一応動きました。

video01.html:5 Uncaught (in promise) NotAllowedError: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD
(匿名) @ video01.html:5

アイコンエラーは関係ないのでスルーで構いません。

favicon.ico:1  GET http://127.0.0.1:5501/favicon.ico 404 (Not Found)

ai icon

はい、完璧な動作環境に見えます!そして、表示されたこのエラー👇について、しっかり補足しておきます:

🎈 video.play() の NotAllowedError の理由

Uncaught (in promise) NotAllowedError: play() failed because the user didn't interact with the document first.

これは ブラウザの自動再生ポリシー(Autoplay Policy) による制限です。

💡 簡単に言うと: 🔒 ユーザーがページ上でクリックやキー入力などの「操作」をするまで、音声付き動画は勝手に再生できない という決まり。

✅ 解決策(回避法) 以下のどれかでOK:

✔ 1. muted 属性を付ける(音無しならOK)

<video id="myVideo" src="..." muted autoplay></video>

👉 音がなければ、ページ読み込みと同時に自動再生できる!

✔ 2. ユーザー操作イベント内で .play() を呼ぶ

document.getElementById("startBtn").addEventListener("click", () => {
  video.play();  // これならOK
});

👉 何かしら「クリック」や「タップ」のあとなら、問題なし!

👀 あなたの現在のコードでは

video.play();  // ← ページ読み込み直後に即再生(✖ ブロックされる)

になっているので、ブラウザに「勝手に鳴らさないで!」と怒られているわけですね。

✅ 今後のオススメ構成

<video id="myVideo" src="..." width="640" controls></video>
<button id="startBtn">再生する</button>

<script>
  const video = document.getElementById("myVideo");
  document.getElementById("startBtn").addEventListener("click", () => {
    video.currentTime = 10;
    video.volume = 0.5;
    video.play();  // これなら確実に通る!
  });
</script>

🧩 favicon.ico の 404 は無視でOK

これは「ページをブックマーク用に小さいアイコンを探してるだけ」なので、気にしなくて大丈夫です。


user icon
ありがとうございます。

「4. Canvasに動画を描画する方法とその応用」
お願いします。

4. Canvasに動画を描画する方法とその応用

HTMLの<video>タグは便利ですが、
より自由にカスタム表示や加工をしたいときには
<canvas>と組み合わせることで、以下のような表現が可能になります。

✅ Canvasで動画を描画する基本構造

<video id="myVideo" src="web-video-sample-01.mp4" style="display:none" muted autoplay></video>
<canvas id="myCanvas" width="640" height="360"></canvas>

<script>
  const video = document.getElementById("myVideo");
  const canvas = document.getElementById("myCanvas");
  const ctx = canvas.getContext("2d");

  video.addEventListener("play", () => {
    function drawFrame() {
      if (!video.paused && !video.ended) {
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height); // 動画のフレームを描画
        requestAnimationFrame(drawFrame); // 次のフレームを予約
      }
    }
    drawFrame(); // 再生開始と同時に描画ループ開始
  });
</script>

■ 補足

コードを見ると display: none になっており、このままでは表示されないので、display: flex に変更しました。

videoタグと、canvas タグ2つで動画が同時に再生されるようです。

🧠 なぜCanvasで描画するのか?

目的 <video>タグで実現できる? <canvas>なら
エフェクトやフィルターをかける
動画の一部を切り取って表示する
複数の動画を合成・マスク処理
ゲーム内の演出、背景に使う
静止画にしたり、GIF化したり

🎛️ 応用:Canvasでセピア・モノクロ加工するには?

ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
let frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
let data = frame.data;

for (let i = 0; i < data.length; i += 4) {
  const avg = (data[i] + data[i+1] + data[i+2]) / 3;
  data[i] = avg;     // 赤
  data[i+1] = avg;   // 緑
  data[i+2] = avg;   // 青
}

ctx.putImageData(frame, 0, 0);

サンプル

🚀 メリットとデメリット

👍 メリット:

  • フレーム単位で自由に描画できる
  • 映像演出やゲーム演出に最適
  • 合成やトラッキング処理と相性抜群

👎 デメリット:

  • 処理が重くなる(高負荷)
  • 音声は別に video 側で鳴らす必要がある
  • スマホではパフォーマンスに注意

✨ 使用例(こんなとき便利)

  • 🎮 ゲーム中の「追憶シーン」に動画再生+ブラー処理
  • 🎞️ タイトル画面で背景にループ動画を流す
  • 🔍 動画に文字・アイコンを重ねて「AR風UI」を実現

5. WebGL / Three.jsによる動画テクスチャ活用

<video>タグや<canvas>では制御しきれない3D的な演出や空間表現をしたいとき、
Three.jsを使うことで、動画を「動くテクスチャ」として扱うことが可能になります。

🎬 動画をThree.jsのテクスチャに貼り付ける構造

<video id="myVideo" src="web-video-sample-01.mp4" autoplay loop muted></video>
<canvas id="myCanvas"></canvas>
// 初期設定
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('myCanvas') });
renderer.setSize(window.innerWidth, window.innerHeight);

// 動画テクスチャ
const video = document.getElementById('myVideo');
const texture = new THREE.VideoTexture(video);

// 3Dオブジェクト(例:平面)
const geometry = new THREE.PlaneGeometry(4, 2.25); // 16:9比
const material = new THREE.MeshBasicMaterial({ map: texture });
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);

// カメラ配置
camera.position.z = 5;

// アニメーションループ
function animate() {
  requestAnimationFrame(animate);
  plane.rotation.y += 0.005;
  renderer.render(scene, camera);
}
animate();

サンプル

🧠 なぜThree.jsで動画を使うの?

表現 video/canvas WebGL/Three.js
テクスチャとして立体に貼る
複数視点カメラでの表示
リアルタイム光源・シャドウ
VR/AR空間との連携
SF的インターフェース(HUD表示)

🧩 応用アイデア

  • 🔺 動画を三角柱や球体の表面に貼る
  • 🪞 背景に360度全天球動画を使って「没入UI」
  • 📺 動画をブラウン管風に歪ませて表示
  • 🎥 3D空間の中に複数の動画を壁面に並べる

⚠️ 注意点

  • スマホではやや重い/パフォーマンス要確認
  • 音声を使う場合は別途制御が必要(通常videoのまま再生)
  • 動画の解像度とファイルサイズに注意

🔧 Three.js導入方法(簡易)

<script src="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script>

サンプルコード

AIのコードを修正した動作サンプルコードを貼っておきます。

<video width="300px" id="myVideo" src="web-video-sample-01.mp4" autoplay loop muted></video>
<canvas id="myCanvas"></canvas>

<script type="module">
  import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.152.0/build/three.module.js";

  // 初期設定
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
  const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("myCanvas") });
  renderer.setSize(window.innerWidth, window.innerHeight);

  // 動画テクスチャ
  const video = document.getElementById("myVideo");
  const texture = new THREE.VideoTexture(video);

  // 3Dオブジェクト(例:平面)
  const geometry = new THREE.PlaneGeometry(4, 2.25); // 16:9比
  const material = new THREE.MeshBasicMaterial({ map: texture });
  const plane = new THREE.Mesh(geometry, material);
  scene.add(plane);

  // カメラ配置
  camera.position.z = 5;

  // アニメーションループ
  function animate() {
    requestAnimationFrame(animate);
    plane.rotation.y += 0.005;
    renderer.render(scene, camera);
  }
  animate();
</script>

🧠 補足:Canvas→Three.jsへの橋渡しも可能

たとえば、canvasに描画した動画にフィルターをかけて、
そのcanvasをThree.jsのCanvasTextureとして使う…というハイブリッドも可能です!

6. メリット・デメリットと使い分け指針

💡 手法ごとの特徴まとめ

手法 長所 短所 向いている場面
video タグ シンプル・高速/ブラウザが自動最適化/字幕やコントロールバーが使える カスタマイズ性が低い/タイミング制御が甘い 通常の映像プレイヤー、簡易再生
JS制御つき video 任意のシーク・速度・音量など制御可能 autoplay制限/イベント管理が必要 操作連動、演出タイミングが大事なUI
canvas 描画 描画位置自由/他コンテンツと混合表示OK 音声が別制御/画質低下のリスク/重い ゲームUI/複数レイヤー構成のアニメ/可視化
WebGL / Three.js 3D空間・動画の歪み・多視点/インタラクティブな演出が可能 ライブラリ学習コスト/モバイルパフォーマンス課題 VR/AR/世界観演出/UIの立体化

🎯 選び方の実践ガイド

  • まず再生できればよい/制御は不要
    • → video タグだけでOK!
  • UIや音ゲーのような演出タイミングと同期したい
    • → JS制御つき video + DOM連携を。
  • UIと動画を組み合わせたい/透明・加工したい
    • → canvas へ動画を描画しよう。
  • 世界観そのものに組み込みたい/3D空間で扱いたい
    • → WebGL or Three.js一択。

⚠️ よくある落とし穴

落とし穴 解説
video.play() が動かない ユーザー操作が必要。イベントハンドラ内で呼び出すべき
<canvas>では音が鳴らない 音声は<video>側で別に再生・制御が必要
Three.jsで動画が止まって見える renderer.render()がアニメーションループで常時呼ばれているか確認
iPhoneで全画面動画が崩れる iOS Safariの仕様。playsinline muted を忘れずに
  • クロスブラウザ対応を考慮
    • → mp4(H.264)が最も互換性高いが、WebMやAV1にも注意
  • 再生速度やループ設定
    • → .playbackRate = 1.5 や .loop = true で動的制御も可
  • 動画の先読み・遅延読み込み
    • → preload=“auto” or lazy設定、JSで遅延ロード可

🔚 結論:目的に応じて「段階的に」使い分ける

  • 最初は video タグで試す
  • 表現が必要ならJS制御
  • 描画が必要ならCanvas
  • 世界を構築するならThree.jsへ

まさに「必要は表現を進化させる」です。

7. 各方式のサンプルコード(複数同時表示や切り替え)

🧩 サンプル1:複数の video を同時に表示・再生

<video src="video1.mp4" width="320" controls></video>
<video src="video2.mp4" width="320" controls></video>

注意点:

  • 同時に再生可能だが、autoplayが効かない場合あり
  • 音が被るので .muted = true にするのが◎
const videos = document.querySelectorAll("video");
videos.forEach(video => {
  video.muted = true;
  video.play();
});
🧩 サンプル1:複数の video を同時に表示・再生

サンプル

🌀 サンプル2:切り替え式の video プレイヤー

<video id="mainVideo" width="640" controls></video>
<button onclick="switchVideo('video1.mp4')">動画①</button>
<button onclick="switchVideo('video2.mp4')">動画②</button>

<script>
function switchVideo(src) {
  const v = document.getElementById("mainVideo");
  v.src = src;
  v.play();
}
</script>
  • JSで src を動的に切り替え
  • v.load() は不要(src変更だけで即反映される)
🌀 サンプル2:切り替え式の video プレイヤー

サンプル

🧪 サンプル3:Canvasに2つの動画を交互に描画

<canvas id="myCanvas" width="640" height="360"></canvas>
<video id="v1" src="video1.mp4" muted autoplay loop style="display:none"></video>
<video id="v2" src="video2.mp4" muted autoplay loop style="display:none"></video>

<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const v1 = document.getElementById("v1");
const v2 = document.getElementById("v2");
let useV1 = true;

function draw() {
  const video = useV1 ? v1 : v2;
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  requestAnimationFrame(draw);
}
draw();

// 5秒ごとに切り替え
setInterval(() => useV1 = !useV1, 5000);
</script>
  • Canvasでは drawImage(video) が使える
  • 音声は動画タグ側で鳴らす or ミュートしてBGMで演出
🧪 サンプル3:Canvasに2つの動画を交互に描画

サンプル

🌀 サンプル4:Three.jsに貼る動画テクスチャの切り替え

const video = document.createElement("video");
video.src = "video1.mp4";
video.muted = true;
video.loop = true;
video.play();

const texture = new THREE.VideoTexture(video);
const material = new THREE.MeshBasicMaterial({ map: texture });

const geometry = new THREE.PlaneGeometry(16, 9);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// 切り替え例
function changeVideo(src) {
  video.pause();
  video.src = src;
  video.load();
  video.play();
}
  • Three.jsでは video を直接作り、VideoTextureとして使う
  • 動画ファイルは .loop, .muted, .play() を忘れずに
🌀 サンプル4:Three.jsに貼る動画テクスチャの切り替え

サンプル

🧠 補足:UX的に切り替えるタイミング

  • 再生ボタン押下で切り替え:意図が明確で安心
  • 自動切り替え:注意喚起がないと混乱される
  • 選択肢+動画提示:ゲームやUIで効果的

✅ まとめ

  • video は複数表示も切り替えも簡単
  • Canvasでは、自由な合成が可能
  • Three.jsでは、3D構成ができるが制御はJS任せ
  • 「切り替え」と「再生開始」はUX面でも気配りを!

📌 8. まとめと応用アイデア

本記事では、Webアプリ上で動画を再生するためのさまざまな手法を紹介しました。

手法 特徴・用途例
<video>タグのみ 最も簡単・確実な方法。記事・ブログに埋め込む用途に◎
<video>+JavaScript制御 再生位置・音量・状態の動的制御が可能。ゲームUIやサウンド連携に◎
Canvasで描画 ゲームの中での表現や、フィルタ加工・UI統合に最適
WebGL / Three.jsで描画 空間的表現や奥行き、3D空間の中での再生。演出や没入感UPに◎

💡 今後の応用アイデア

🎮 ゲームへの応用

  • 特定キャラクターの登場時にムービー再生
  • 裏モードへの移行時にだけ流れる“闇演出”映像
  • 動画で描かれた“記録”を探索していくADV演出

🧩 UI/UX向け活用

  • UI部品に動画を貼り付けて「動くボタン」や「動く背景」
  • トランジション時に動画で視線を誘導する演出

🎨 デザイン演出

  • モーショングラフィックスを動画で用意 → CanvasThree.jsで合成
  • 複数の動画を同時再生してインスタレーションのような表現も可能

🛠 おすすめの発展ステップ

  • requestVideoFrameCallback を使った高精度同期(上級者向け)
  • PWAと連携して「動画付きWebアプリ」をスマホでホームアプリ化
  • 動画素材をIndexedDBに保存・ロード → オフライン再生対応

🧠 最後に

動画再生は video タグから一歩踏み出すと、 「演出装置」「データ可視化」「UXツール」など、 とても多彩な可能性を秘めています。

あなたのアプリやゲームに最適な方法を選び、 その“映像体験”を自由にデザインしてください。