プロジェクトの操作方法を説明するとき、文章やスクリーンショットだけでは伝わりにくいことがあります。
短いデモ動画があれば、セットアップ後の画面、UIの操作手順、アニメーション、修正前後の違いなどを数十秒で見せられます。一方で、画面収録したMP4をそのままリポジトリへ追加すると、別の問題が発生します。
- リポジトリの容量が増える
- cloneやfetchに時間がかかる
- ドキュメントページの読み込みが遅くなる
- モバイル回線で再生しにくい
- 動画を更新するたびにGit履歴が膨らむ
この記事では、READMEや技術ドキュメント用の動画に容量上限を設定し、公開用MP4を作成して、サイズ超過をCIで防ぐ方法をまとめます。
前提:元動画と公開用動画を分ける
最初に決めておきたいのは、編集前の元動画をGitリポジトリへ入れないことです。
元動画は高解像度かつ高ビットレートで保存されていることが多く、数十秒でも容量が大きくなります。さらに、動画は差分管理に向いていないバイナリファイルです。一部だけを修正しても、Git上では新しい大きなファイルとして履歴に残ります。
今回は次のように役割を分けます。
元動画
└─ ローカルストレージまたはクラウドへ保存
公開用動画
├─ 解像度とビットレートを調整
├─ 不要部分をカット
└─ CDN、オブジェクトストレージ、Releaseなどで配信
リポジトリ
├─ README.md
├─ docs/
├─ scripts/check-demo-video-size.mjs
└─ public/posters/
READMEやドキュメントには、公開用動画のURLと軽量なポスター画像だけを記述します。
動画の容量予算を先に決める
圧縮率だけで考えると、動画ごとに結果がばらつきます。「元の50%まで圧縮する」ではなく、用途ごとに上限を決めたほうが管理しやすくなります。
例えば、チーム内で次のような基準を設定できます。
| 用途 | 再生時間 | 目標容量 | 解像度の目安 |
|---|---|---|---|
| READMEの短い操作デモ | 10~20秒 | 3MB以下 | 720p |
| ドキュメントの機能紹介 | 20~40秒 | 5MB以下 | 720p |
| Releaseの詳細デモ | 1分前後 | 10MB以下 | 720p~1080p |
これは絶対的な正解ではありません。重要なのは、プロジェクト内で基準を統一することです。
文字の多い画面収録では解像度を下げすぎるとUIが読めなくなります。一方、単純なアニメーションや画面遷移なら、フレームレートやビットレートを下げても内容を理解できる場合があります。
公開用MP4を作る
FFmpegを利用できる環境では、次のようにH.264形式のMP4を作成できます。
ffmpeg \
-i demo-original.mov \
-vf "scale=-2:720,fps=24" \
-c:v libx264 \
-crf 26 \
-preset medium \
-c:a aac \
-b:a 96k \
-movflags +faststart \
demo-web.mp4
主な設定は次のとおりです。
-
scale=-2:720:縦を720pxにし、横幅を自動調整 -
fps=24:フレームレートを24fpsに変更 -
crf 26:画質と容量のバランスを調整 -
b:a 96k:音声ビットレートを96kbpsに設定 -
+faststart:MP4のメタデータを先頭へ移動し、Web再生を開始しやすくする
音声が不要な操作デモなら、-anを指定して音声を削除できます。
ffmpeg \
-i demo-original.mov \
-vf "scale=-2:720,fps=24" \
-c:v libx264 \
-crf 26 \
-preset medium \
-an \
-movflags +faststart \
demo-web.mp4
コマンドライン環境を用意せず、その場で公開用コピーを作りたい場合は、ブラウザ上で使えるVideo Compressorを選択肢にできます。元動画を直接上書きせず、READMEやドキュメントで使用するコピーとして出力し、完成後に文字の読みやすさ、音声、再生時間を確認します。
どちらの方法でも、一度圧縮した動画を再び圧縮するのではなく、調整が必要な場合は元動画から作り直します。
Node.jsでステージ済み動画のサイズを確認する
動画の容量ルールを決めても、レビューだけに頼ると見落としが発生します。
そこで、Gitにステージされた動画を調べ、上限を超えていたら終了コード1を返すスクリプトを用意します。
scripts/check-demo-video-size.mjsを作成します。
import fs from "node:fs";
import { execFileSync } from "node:child_process";
const MAX_BYTES = 8 * 1024 * 1024;
const VIDEO_EXTENSIONS = new Set([
".mp4",
".mov",
".webm",
".m4v",
]);
const output = execFileSync(
"git",
[
"diff",
"--cached",
"--name-only",
"--diff-filter=ACMR",
"-z",
],
{ encoding: "utf8" }
);
const files = output
.split("\0")
.filter(Boolean)
.filter((file) => {
const dotIndex = file.lastIndexOf(".");
if (dotIndex === -1) return false;
return VIDEO_EXTENSIONS.has(
file.slice(dotIndex).toLowerCase()
);
});
const oversized = [];
for (const file of files) {
if (!fs.existsSync(file)) continue;
const size = fs.statSync(file).size;
if (size > MAX_BYTES) {
oversized.push({
file,
sizeMiB: (size / 1024 / 1024).toFixed(2),
});
}
}
if (oversized.length > 0) {
console.error(
`動画ファイルは8 MiB以下にしてください。`
);
for (const item of oversized) {
console.error(
`- ${item.file}: ${item.sizeMiB} MiB`
);
}
process.exit(1);
}
console.log("動画ファイルのサイズは上限内です。");
package.jsonに実行コマンドを追加します。
{
"scripts": {
"check:demo-video": "node scripts/check-demo-video-size.mjs"
}
}
次のコマンドで確認できます。
npm run check:demo-video
このスクリプトはステージ済みのファイルだけを対象にするため、ローカルに保存している元動画までは検査しません。
pre-commitでコミット前に止める
Huskyを使っているプロジェクトなら、pre-commitフックからスクリプトを呼び出せます。
npx husky init
.husky/pre-commitに次の処理を追加します。
npm run check:demo-video
これで、上限を超えたMP4やMOVを誤ってコミットしようとした場合、その場で処理を止められます。
ただし、ローカルフックは各開発者が無効化できます。確実に適用したい場合は、CI側でも同じ検査を実行します。
GitHub Actionsでも容量を検査する
Pull Requestで確認する場合は、次のワークフローを追加します。
.github/workflows/check-demo-video.yml
name: Check demo video size
on:
pull_request:
paths:
- "**/*.mp4"
- "**/*.mov"
- "**/*.webm"
- "**/*.m4v"
- "scripts/check-demo-video-size.mjs"
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Stage changed video files
run: |
git diff --name-only -z \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.sha }}" \
-- '*.mp4' '*.mov' '*.webm' '*.m4v' \
| xargs -0 -r git add --
- name: Check video size
run: node scripts/check-demo-video-size.mjs
この例では、Pull Request内で変更された動画を一度ステージし、ローカルと同じNode.jsスクリプトで検査しています。
プロジェクトの運用に合わせて、MAX_BYTESを環境変数から取得する設計にしてもよいでしょう。
ドキュメントサイトでは動画を先読みしない
Docusaurus、VitePress、Astroなどで作成したドキュメントサイトに動画を置く場合、MP4自体を軽くするだけでなく、読み込み方も指定します。
<video
controls
playsinline
preload="none"
poster="/posters/dashboard-demo.webp"
width="960"
>
<source
src="https://cdn.example.com/videos/dashboard-demo.mp4"
type="video/mp4"
/>
お使いのブラウザは動画再生に対応していません。
</video>
preload="none"を指定すると、ユーザーが再生する前に動画データを先読みしません。posterには、再生前に表示する軽量な画像を指定します。
同じページに複数のデモ動画がある場合、何も設定せずにすべてを読み込ませるより、初期表示への影響を抑えやすくなります。
READMEではポスター画像から動画へリンクする
READMEでは、動画を直接リポジトリへ置くより、ポスター画像を表示して外部の動画へリンクする構成が扱いやすくなります。
[](
https://cdn.example.com/videos/dashboard-demo.mp4
)
ユーザーは画像をクリックすると動画を開けます。
この方法には次の利点があります。
- READMEの初期表示が軽い
- リポジトリへ大きな動画を追加せずに済む
- 動画の配信先を分離できる
- 再生前に内容をポスター画像で伝えられる
アクセシビリティのため、画像の代替テキストにも「操作デモ」など内容が分かる説明を入れます。
公開前に確認する項目
圧縮が完了したら、容量だけでなく内容も確認します。
- UIの文字を読めるか
- マウスポインターの位置が分かるか
- 映像と音声がずれていないか
- 最後まで再生できるか
- 黒画面や不要な待ち時間が含まれていないか
- APIキー、メールアドレス、通知などが映っていないか
- 実在ユーザーのデータを表示していないか
- 動画URLへ権限なしでアクセスできるか
特に画面収録では、個人情報や開発環境の秘密情報が入りやすいため、容量チェックとは別に目視確認が必要です。
よくある質問
README用のMP4は何MBまでにすべきですか?
一律の正解はありませんが、短い操作デモなら数MB程度を目標にすると管理しやすくなります。この記事の例では、チーム独自の上限として8MiBを設定しています。
動画はGit LFSへ保存すれば圧縮しなくてもよいですか?
Git LFSは大きなファイルを通常のGitオブジェクトとは別に管理する仕組みです。しかし、ドキュメントの読み込み速度や閲覧者の通信量は改善しないため、公開用動画の軽量化は別途必要です。
GIFとMP4のどちらがよいですか?
短い無音アニメーションでも、GIFは色数や圧縮効率の面で容量が大きくなることがあります。再生環境に問題がなければ、操作デモにはMP4やWebMを検討し、READMEではポスター画像からリンクする方法も使えます。
動画の画質をどこまで下げられますか?
UIの文字、カーソル、エラー表示など、動画の目的に必要な情報が読める範囲までです。容量だけで判断せず、実際のドキュメント幅とスマートフォンの両方で確認します。
まとめ
READMEや技術ドキュメントへ動画を追加するときは、圧縮を公開直前の作業にしないことが重要です。
- 元動画と公開用動画を分ける
- 用途ごとに容量上限を決める
- MP4を軽量化してから公開する
- 動画本体をGitの外へ置く
- pre-commitとCIでサイズを検査する
-
preloadとposterでページ読み込みを調整する - 公開前に文字、音声、個人情報を確認する
このルールをリポジトリへ残しておけば、担当者が変わっても同じ基準でデモ動画を管理できます。