fqmpeg の C8 クラスタは「動画の上に何かを乗せる、もしくは横に並べる」13動詞の合成ツールボックスだ。静的なグラフィックやテキストを描く5つ(watermark, text, drawbox, timecode, border)、複数動画を1枚のキャンバスに合成する4つ(pip, pip-grid, blend, stack)、静止画と音声から動画を作る1つ(picture)、そしてレビュー用に解析情報をフレームに焼き付ける3つ(video-info-overlay, histogram-overlay, progress)。
この記事は fqmpeg 3.0.3 の src/commands/ を実読して、各動詞が叩いている FFmpeg フィルタ・デフォルト値・出力ファイル名・そして --help だけだと見えない落とし穴を全部洗い出したものだ(text は : と ' を自動エスケープしてくれるのでそのまま書ける、pip-grid は入力本数からレイアウト(2x1/2x2/3x3)を自動判定する、progress はフィルタ式の中から動画の総尺を参照できないので duration を引数で渡す必要がある、histogram-overlay の表示位置とサイズはハードコード)。
この記事で得られるもの
- 13動詞をタスク別(グラフィック/合成/静止画→動画/解析)に選び分ける早見表
- 各動詞が実際に生成する FFmpeg コマンド(
--dry-runで検証済み) - 全コマンドのデフォルト値・範囲・位置キーワード・出力ファイル名
- 「YouTube 用にブランディング」「比較リール」「画面録画ドキュメント化」の実用レシピ3本
13動詞の全体像
クラスタはタスク別に4グループに分かれる。グループを決めてから動詞を選ぶ流れがラク。
| グループ | 動詞 | 用途 |
|---|---|---|
| 静的グラフィック・テキスト | watermark, text, drawbox, timecode, border | ロゴ画像・テキスト・矩形・タイムコード・装飾フレームを焼き付ける |
| 複数動画の合成 | pip, pip-grid, blend, stack | ピクチャ・イン・ピクチャ、2-9入力グリッド、不透明度ブレンド、左右/上下並べ |
| 静止画→動画 | picture | 静止画+音声から再生可能な MP4 を作る(ポッドキャスト・楽曲動画) |
| 解析オーバーレイ | video-info-overlay, histogram-overlay, progress | フレーム番号/PTS/ピクチャタイプ、ヒストグラム/波形、時間連動プログレスバー |
読み進める前に知っておくと得な3点:
textは:と'を自動エスケープしてくれる。drawtextフィルタは:をオプション区切り、'を文字列デリミタとして扱うので、本来Time: 12:34のような文字列は手で\:にエスケープが必要。fqmpeg 側で'→'\\\\''、:→\:に変換してから埋め込んでくれるので、シェルクオートだけ気にすればそのまま書ける。逆に「文字列の中からdrawtextのオプションを差し込む」ような攻撃的な使い方はブロックされる仕様。pip-gridは入力本数からレイアウトを自動判定する。 2本なら2x1、3-4本で2x2、5-9本で3x3。グリッドの空きスロットは「最後の入力」で埋められる — 5本を3x3に渡すと 6-9 番目のスロットは入力5のクローン。意図的に形を固定したい時は--layout 2x2で明示する。progressは<duration>を位置引数で渡す必要がある。 FFmpeg のdrawbox式はt(現在再生時刻)は参照できるが、ソースの総尺を表す式が無い。fqmpeg はワークアラウンドとして duration を引数で取り、iw*t/<duration>の式に焼き込む。総尺が不明なら先にnpx fqmpeg duration input.mp4で測ってから渡す。
静的グラフィック・テキスト
watermark — 画像オーバーレイ(PNG ロゴなど)
動画の上に画像を9つのプリセット位置のいずれかで重ねる。音声はコピーで触らない。
- ソース:
src/commands/watermark.js - フィルタ:
overlay=<x>:<y>(<x>:<y>は--posと--marginから計算) - 音声:
-c:a copy(無加工)
| 引数 / オプション | デフォルト | 選択肢・備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
<image> | 必須 | ウォーターマーク画像(透過 PNG 推奨) |
--pos <position> | bottom-right | top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right |
--margin <n> | 10 | 端からのマージン(ピクセル) |
-o, --output <path> | <入力名>-watermarked.<拡張子> | — |
$ npx fqmpeg watermark input.mp4 logo.png --pos bottom-right --margin 10 --dry-run
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w-10:H-h-10 -c:a copy input-watermarked.mp4
画像の元サイズがそのまま使われる — --scale は無い。ロゴが大きすぎる時は画像エディタか、事前に ffmpeg -i logo.png -vf scale=120:-1 logo-small.png でリサイズしておく。中央寄せ系の位置(top, bottom, center, left, right)は中心軸からの計算なので、--margin は片方の軸にしか効かない(例: bottom は下端からのマージンだけが効き、横方向は中央固定)。
text — タイトル・テロップを焼き付ける
文字列を7つのプリセット位置に焼き付ける。背景ボックスや表示時間ウィンドウもオプション。
- ソース:
src/commands/text.js - フィルタ:
drawtext=text='<エスケープ済み>':fontsize=N:fontcolor=C:<pos>[:box=1:boxcolor=...][:enable='...'] - 自動エスケープ: 入力文字列の
'と:は埋め込み前に変換される
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
<string> | 必須 | 描画する文字列(位置引数。シェルの特殊文字は自分でクオート) |
--pos <position> | center | top-left, top, top-right, center, bottom-left, bottom, bottom-right |
--font-size <n> | 48 | 正の整数 |
--color <name> | white | FFmpeg のカラー名 or 0xRRGGBB |
--bg <color> | (なし) | 背景ボックス色(例: black@0.5 で 50% 不透明) |
--start <sec> | (なし) | この時刻から表示 |
--end <sec> | (なし) | この時刻で非表示 |
-o, --output <path> | <入力名>-text.<拡張子> | — |
$ npx fqmpeg text input.mp4 "Hello, World" --pos top --font-size 64 --color yellow --bg black@0.5 --dry-run
ffmpeg -i input.mp4 -vf "drawtext=text='Hello, World':fontsize=64:fontcolor=yellow:x=(w-text_w)/2:y=20:box=1:boxcolor=black@0.5:boxborderw=8" -c:a copy input-text.mp4
コロンとアポストロフィを含む文字列もそのまま渡せる — --bg "black@0.5" も text "Time: 12:34" も手動エスケープは不要。boxborderw=8(ボックス内側の余白8ピクセル)はハードコードなので、もっと余白を減らしたい/増やしたい時は --dry-run をコピーして編集する。複数行は drawtext 自体に折返し機能が無いので、文字列の中に \n を入れて改行を明示する(多くのビルドで動くが行間調整は line_spacing=N を手で足す必要があるかも)。
--start と --end は drawtext の enable 式で時間ウィンドウを作る。片方だけなら gte(t,N) か lte(t,N)、両方なら between(t,A,B) が生成される。
drawbox — 矩形を描画する
固定位置に矩形(枠線 or 塗りつぶし)を描く。チュートリアルで「ここに注目」を強調する、固定領域をマスクする、画面録画にマークアップする、といった用途。
- ソース:
src/commands/drawbox.js - フィルタ:
drawbox=x=X:y=Y:w=W:h=H:color=C:t=T[:enable='...'] - 領域フォーマット:
x:y:w:hの厳格 regex — 違うフォーマットはError: region must be x:y:w:hで終了
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
<region> | 必須 | x:y:w:h(左上原点のピクセル座標) |
--color <name> | red | FFmpeg カラー名 |
--thickness <n> | 3 | 正の整数 or 文字列 fill(塗りつぶし) |
--start <sec> | (なし) | この時刻から表示 |
--end <sec> | (なし) | この時刻で非表示 |
-o, --output <path> | <入力名>-boxed.<拡張子> | — |
$ npx fqmpeg drawbox input.mp4 100:50:200:150 --color yellow --thickness fill --dry-run
ffmpeg -i input.mp4 -vf drawbox=x=100:y=50:w=200:h=150:color=yellow:t=fill -c:a copy input-boxed.mp4
--thickness fill は「個人情報マスク」のパターン — 単色で領域を覆い隠す。枠線だけのハイライト用途なら正の整数(1080p なら 3–8 が読みやすい)。--start/--end と組み合わせれば、チュートリアルで「ここを説明する数秒だけ枠を出す」が一発で書ける。座標は絶対ピクセル指定なので、相対指定したい時は npx fqmpeg info input.mp4 で先にフレームサイズを調べる。
timecode — 再生時刻を焼き付ける
動画の現在再生位置を HH:MM:SS.mmm 形式で、半透明の黒ボックス付きで角に表示する。
- ソース:
src/commands/timecode.js - フィルタ:
drawtext=text='%{pts\\:hms}':fontsize=N:fontcolor=C:<pos>:box=1:boxcolor=black@0.5:boxborderw=4 - フォーマット:
%{pts:hms}— FFmpeg ビルトインの HMS フォーマッタ(ハードコードなので他形式は不可)
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
--pos <position> | top-left | top-left, top-right, bottom-left, bottom-right(角のみ) |
--font-size <n> | 24 | 正の整数 |
--color <name> | white | FFmpeg カラー名 |
-o, --output <path> | <入力名>-timecode.<拡張子> | — |
$ npx fqmpeg timecode input.mp4 --pos top-right --font-size 32 --dry-run
ffmpeg -i input.mp4 -vf drawtext=text='%{pts\:hms}':fontsize=32:fontcolor=white:x=w-text_w-10:y=10:box=1:boxcolor=black@0.5:boxborderw=4 -c:a copy input-timecode.mp4
レビュー用リールに便利 — クライアントが「0:01:22.500 のカットが硬い」と時刻指定でフィードバックしてくるので、確認の往復が一発で終わる。黒ボックスは明るいシーンでも視認できるようにハードコード。違うフォーマット(フレーム番号、ソースタイムコード、カスタム接頭辞)が欲しい時は、text で %{pts} / %{n} / %{localtime} を直接書くか、後述の video-info-overlay を使う。
border — 装飾フレームを足す
四方を単色でパッドする。出力サイズが片軸あたり 2 * width ピクセル増える。
- ソース:
src/commands/border.js - フィルタ:
pad=iw+W*2:ih+W*2:W:W:color=C
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
--width <px> | 20 | 各辺に追加されるボーダー厚(ピクセル) |
--color <name> | white | FFmpeg カラー名 |
-o, --output <path> | <入力名>-bordered.<拡張子> | — |
$ npx fqmpeg border input.mp4 --width 30 --color black --dry-run
ffmpeg -i input.mp4 -vf pad=iw+30*2:ih+30*2:30:30:color=black -c:a copy input-bordered.mp4
出力サイズが大きくなる — 1920x1080 のソースに --width 30 で 1980x1140 になる。アスペクト比を厳しく見るプラットフォーム(Instagram の 1:1 ポスト、YouTube Shorts の 9:16)は再クロップしてくるので、ターゲットの仕様を先に確認する。縦動画を正方形フレームにしたい時は、--width を「ソース幅と狙う正方形辺の差の半分」に設定して、crop と組み合わせるほうが制御しやすい。
複数動画の合成
pip — ピクチャ・イン・ピクチャ
「サブ」動画をスケールダウンして「メイン」動画の四隅のいずれかに重ねる。
- ソース:
src/commands/pip.js - フィルタ:
[1]scale=iw*S:ih*S[pip];[0][pip]overlay=<xy> - 音声: 明示指定なし — メイン動画(最初の入力)のオーディオが FFmpeg のデフォルト挙動でそのまま通る
| 引数 / オプション | デフォルト | 範囲 | 備考 |
|---|---|---|---|
<main> | 必須 | — | 背景動画 |
<small> | 必須 | — | オーバーレイ動画 |
--pos <position> | bottom-right | — | top-left, top-right, bottom-left, bottom-right |
--scale <n> | 0.25 | 0.1–1.0 | メインに対するオーバーレイの縮小率 |
--margin <n> | 10 | 正の整数 | 端からのピクセル距離 |
-o, --output <path> | <main名>-pip.<拡張子> | — | — |
$ npx fqmpeg pip main.mp4 webcam.mp4 --pos top-right --scale 0.3 --dry-run
ffmpeg -i main.mp4 -i webcam.mp4 -filter_complex [1]scale=iw*0.3:ih*0.3[pip];[0][pip]overlay=main_w-overlay_w-10:10 main-pip.mp4
定番の使い方は「画面録画 = メイン」「ウェブカム = サブ」を25%スケールで角に置く構成。出力の長さはメイン動画準拠なので、サブが短ければ最終フレームでフリーズし、長ければカットされる。サブの最終フレームで延長したい時は tpad=stop_mode=clone を事前にかけるか、サブに対して先に repeat-frame 動詞をかける。
pip-grid — マルチ入力グリッド合成
2-9本の動画をグリッド(2x1, 1x2, 2x2, 3x3)に並べる。--layout 省略時は入力本数から自動判定。
- ソース:
src/commands/pip-grid.js - フィルタ: 各入力を
scale=iw/cols:ih/rows、各行hstack、最後にvstack - 空きスロット: 最後の入力で埋める
- 音声: 入力0からコピー(
-c:a copy)
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<inputs...> | 必須 | 2-9本の入力動画(位置引数、可変長) |
--layout <grid> | 自動 | 2x1, 1x2, 2x2, 3x3。自動: 2→2x1, 3-4→2x2, 5-9→3x3 |
-o, --output <path> | <入力0名>-grid<layout>.<拡張子> | — |
$ npx fqmpeg pip-grid clip1.mp4 clip2.mp4 clip3.mp4 clip4.mp4 --layout 2x2 --dry-run
ffmpeg -i clip1.mp4 -i clip2.mp4 -i clip3.mp4 -i clip4.mp4 \
-filter_complex '[0:v]scale=iw/2:ih/2[v0];
[1:v]scale=iw/2:ih/2[v1];
[2:v]scale=iw/2:ih/2[v2];
[3:v]scale=iw/2:ih/2[v3];
[v0][v1]hstack=inputs=2[row0];
[v2][v3]hstack=inputs=2[row1];
[row0][row1]vstack=inputs=2[out]' \
-map '[out]' -c:a copy clip1-grid2x2.mp4
5本を 3x3 に渡すとスロット6-9は入力5のクローンになる。「同じ台詞のテイク5つを9-up でレビュー」みたいな用途なら便利だが、本数の渡し間違いだと意図しない複製になるので注意。3x3 で意図的に空きスロットを残したい時は、黒画面動画を別途作って入力に混ぜる(fqmpeg は空のスロットを合成してくれない)。各入力は iw/cols:ih/rows で機械的にスケールされるので、アスペクト比の違う動画を混ぜると不均一に伸縮される — 揃えたければ事前に resize か crop を通す。
blend — 不透明度ブレンド
2本の動画を、2本目を任意の透明度で重ねる形で合成する。
- ソース:
src/commands/blend.js - フィルタ:
[1]format=yuva420p,colorchannelmixer=aa=O[over];[0][over]overlay - 音声: 再エンコード(
-c:a copy指定なし)
| 引数 / オプション | デフォルト | 範囲 | 備考 |
|---|---|---|---|
<input1> | 必須 | — | ベース(下)動画 |
<input2> | 必須 | — | オーバーレイ(上)動画 |
--opacity <n> | 0.5 | 0–1 | 入力2のアルファ |
-o, --output <path> | <入力1名>-blend.<拡張子> | — | — |
$ npx fqmpeg blend input1.mp4 input2.mp4 --opacity 0.5 --dry-run
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex [1]format=yuva420p,colorchannelmixer=aa=0.5[over];[0][over]overlay input1-blend.mp4
2本の動画は空間的に合っている必要がある — blend は 0:0 で重ねるので解像度が違うとずれる。事前にオーバーレイ側を resize でベースに合わせる。出力長は FFmpeg overlay のデフォルトに従う(短いほうに合わせるのが一般的)。「残像エフェクト」狙いなら --opacity 0.3–0.4。0.7 を超えるとベース動画がほぼ見えなくなる。
stack — 左右並べ・上下並べ
2本の動画を1フレームに並べる。横並び(horizontal)は高さ一致、縦並び(vertical)は幅一致が前提。
- ソース:
src/commands/stack.js - フィルタ:
[0:v][1:v]hstack=inputs=2またはvstack=inputs=2 - 音声:
-c:a copy(入力0のトラック)
| 引数 / オプション | デフォルト | 選択肢 | 備考 |
|---|---|---|---|
<input1> | 必須 | — | 左/上の動画 |
<input2> | 必須 | — | 右/下の動画 |
--direction <dir> | horizontal | horizontal, vertical | — |
-o, --output <path> | <入力1名>-stacked.<拡張子> | — | — |
$ npx fqmpeg stack original.mp4 graded.mp4 --direction horizontal --dry-run
ffmpeg -i original.mp4 -i graded.mp4 -filter_complex [0:v][1:v]hstack=inputs=2 -c:a copy original-stacked.mp4
定番の Before / After 比較リール — カラーグレーディング前後、スタビ前後、デノイズ前後など。高さが揃ってないと Input 1 height 720 does not match input 0 height 1080 で落ちるので、npx fqmpeg resize input.mp4 --height 1080 で先に揃える。音声は input1 のものだけ使われ、2本目の音声は捨てられる。
静止画→動画
picture — 静止画 + 音声 → 動画
静止画を音声の長さだけループしてエンコードする。ポッドキャスト1話分や1曲を YouTube 投稿用の動画にする時の定番。
- ソース:
src/commands/picture.js - コーデック:
libx264+aac@192k+yuv420p+-tune stillimage+-shortest - 出力名: 音声ファイル名から派生(画像名ではない)。
<音声名>-video.mp4
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<image> | 必須 | JPG / PNG カバー画像 |
<audio> | 必須 | MP3 / WAV など |
-o, --output <path> | <音声ディレクトリ>/<音声名>-video.mp4 | 派生元は音声側 |
$ npx fqmpeg picture cover.png episode.mp3 --dry-run
ffmpeg -loop 1 -i cover.png -i episode.mp3 -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest episode-video.mp4
-tune stillimage は x264 に「フレームの中身が動かない」ヒントを渡すチューニング — 1枚しか実質的な絵が無いので、極端に低いビットレートでも高画質を維持できる。-shortest は短いほうの入力に合わせて出力を終わらせる指定 — ループ画像は無限長なので、必ず音声長で終わる。出力名が音声ベースなのは「このエピソード/曲を動画化する」というユースケースに合わせた設計。違う名前にしたいなら -o で上書きする。
カバー画像つきポッドキャストでチャプターマーカーも入れたい場合は、picture の後に embed-thumbnail やメタデータ系動詞を別途繋ぐ — fqmpeg は単機能で切り分ける設計。
解析オーバーレイ
この3動詞はフレームに診断データを焼き付ける — QC レビュー、カラコレ作業、フレーム単位で何が起きているかを見せたいチュートリアル動画などで使う。最終納品用ではない。
video-info-overlay — フレーム番号・PTS・ピクチャタイプ
各フレームに「フレーム番号 (%{n})」「再生タイムスタンプ (%{pts:hms})」「ピクチャタイプ (%{pict_type} — H.264 の I/P/B)」をテキストで焼き付ける。
- ソース:
src/commands/video-info-overlay.js - フィルタ:
drawtext=text='frame %{n} | pts %{pts\\:hms} | type %{pict_type}':x=10:y=10:fontsize=16:fontcolor=white:box=1:boxcolor=black@0.5 - 位置・フォント・色: 全部ハードコード(オプション無し)
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
-o, --output <path> | <入力名>-info-overlay.<拡張子> | — |
$ npx fqmpeg video-info-overlay input.mp4 --dry-run
ffmpeg -i input.mp4 -vf "drawtext=text='frame %{n} | pts %{pts\:hms} | type %{pict_type}':x=10:y=10:fontsize=16:fontcolor=white:box=1:boxcolor=black@0.5" -c:a copy input-info-overlay.mp4
「フレーム4523 の P フレームでグリッチが出てる」みたいな QC や、GOP 構造を視覚化するチュートリアルに便利。位置は左上、フォントサイズは16px固定 — 1080p で読める最小限。違うサイズや位置が欲しい時は --dry-run をコピーして編集するか、text 動詞で同じ %{...} 式を自分で組む。
histogram-overlay — RGB / 波形 / パレード
320x240 のヒストグラム(または波形 / パレード)を右下隅に重ねる。カラコレ作業でフレームと一緒にレベル分布を見たい時用。
- ソース:
src/commands/histogram-overlay.js - フィルタ (levels):
split[main][hist];[hist]histogram,scale=320:240[h];[main][h]overlay=W-w-10:H-h-10 - フィルタ (waveform):
split[main][wave];[wave]waveform=mode=column,scale=320:240[w];[main][w]overlay=W-w-10:H-h-10 - フィルタ (parade):
split[main][par];[par]waveform=mode=column:display=parade,scale=320:240[p];[main][p]overlay=W-w-10:H-h-10 - 位置・サイズ: 右下マージン10px、320x240 パネル — どちらもハードコード
| 引数 / オプション | デフォルト | 選択肢 | 備考 |
|---|---|---|---|
<input> | 必須 | — | 入力動画 |
--mode <mode> | levels | levels, waveform, parade | — |
-o, --output <path> | <入力名>-histogram.<拡張子> | — | — |
$ npx fqmpeg histogram-overlay input.mp4 --mode parade --dry-run
ffmpeg -i input.mp4 -filter_complex split[main][par];[par]waveform=mode=column:display=parade,scale=320:240[p];[main][p]overlay=W-w-10:H-h-10 -c:a copy input-histogram.mp4
levels は古典的な256ビン RGB ヒストグラム。waveform は輝度を横位置に対する縦方向の散布で見せる放送用スコープ。parade は waveform を R/G/B チャンネルごとに3列並べたもの。DIY カラコレで分布の動きをスクラブしながら見たい時は parade が一番情報量が多い。
progress — 時間連動プログレスバー
フレームの上端 or 下端に、時間とともに左から伸びる横棒を焼き付ける。
- ソース:
src/commands/progress.js - フィルタ:
drawbox=x=0:y=<y>:w='iw*t/<duration>':h=H:color=C:t=fill - なぜ duration が必要なのか: FFmpeg の
drawbox式はt(現在再生時刻)は参照できるが、ソースの総尺を表す変数が無い。fqmpeg は duration を引数で受けて式に焼き込むことで回避している
| 引数 / オプション | デフォルト | 備考 |
|---|---|---|
<input> | 必須 | 入力動画 |
<duration> | 必須 | 動画の総秒数(npx fqmpeg duration input.mp4 で測れる) |
--pos <position> | bottom | top, bottom |
--color <name> | red | FFmpeg カラー名 |
--height <px> | 5 | 正の整数 |
-o, --output <path> | <入力名>-progress.<拡張子> | — |
$ npx fqmpeg progress input.mp4 90 --pos bottom --color cyan --height 8 --dry-run
ffmpeg -i input.mp4 -vf drawbox=x=0:y=ih-8:w='iw*t/90':h=8:color=cyan:t=fill -c:a copy input-progress.mp4
duration は秒数で渡す — 1分30秒なら 90、1時間なら 3600。バーは t = duration で画面いっぱいに到達する。間違った値を渡すと早く満タンになるか、最後まで埋まらないかのどちらか。実用シェルワンライナーは dur=$(npx fqmpeg duration input.mp4) && npx fqmpeg progress input.mp4 $dur。視聴者が残り時間を視覚で把握できるチュートリアル動画にどうぞ。
実用ユースケース
各レシピは複数動詞を実際の作業フローに繋ぐ例。
レシピ1: YouTube 用にブランディング
完成済み動画にコーナーロゴ・冒頭3秒のタイトル・薄いプログレスバーを追加する。
# Step 1: コーナーウォーターマーク(透過 PNG ロゴ)
npx fqmpeg watermark final.mp4 logo.png --pos bottom-right --margin 20
# → final-watermarked.mp4
# Step 2: 冒頭3秒だけタイトル表示
npx fqmpeg text final-watermarked.mp4 "Episode 12 — Color Grading" \
--pos top --font-size 56 --color white --bg "black@0.5" \
--start 0 --end 3
# → final-watermarked-text.mp4
# Step 3: 薄いプログレスバー(8分エピソード = 480秒)
npx fqmpeg progress final-watermarked-text.mp4 480 --pos bottom --color "white@0.6" --height 4
# → final-watermarked-text-progress.mp4
3パスなので H.264 の世代再エンコードが3回入る。許容範囲だが世代劣化はゼロではない。1パスにしたい時は3つの --dry-run 出力からフィルタ文字列をコピーして ; , で繋いだ FFmpeg 1コマンドにまとめる。週次ポッドキャストみたいに繰り返し回す用途なら、3ステップワークフローのほうが楽でいい — 微小な画質劣化より便利さが勝つ。
レシピ2: タイムコード付き比較リール
カラーグレーディング前後を左右並べて、レビュアーが時刻を指定できるようタイムコードも焼く。
# Step 1: 横並び(高さ一致が前提)
npx fqmpeg stack original.mp4 graded.mp4 --direction horizontal
# → original-stacked.mp4 (1920x1080 が2本なら 3840x1080)
# Step 2: タイムコードを左上に焼き付ける
npx fqmpeg timecode original-stacked.mp4 --pos top-left --font-size 32
# → original-stacked-timecode.mp4
# Step 3 (任意): 各サイドに静的ラベル
npx fqmpeg text original-stacked-timecode.mp4 "ORIGINAL GRADED" \
--pos bottom --font-size 48 --color white --bg "black@0.5"
Step 3 のラベルはスペースで「GRADED」を右寄せに押す乱暴な方法だが意外と通用する。ピクセル精度のラベルが欲しいなら、text を2回呼んで --dry-run をコピーし、--pos 由来の x= を絶対座標に書き換える。
レシピ3: 画面録画にウェブカム + プログレス
12分の画面録画(screen.mp4)とウェブカム(webcam.mp4)から、ウェブカム角配置・プログレスバー・冒頭5秒のタイトル付きチュートリアル動画を作る。
# Step 1: ウェブカムを PIP に
npx fqmpeg pip screen.mp4 webcam.mp4 --pos bottom-right --scale 0.2 --margin 20
# → screen-pip.mp4
# Step 2: プログレスバー(12分 = 720秒)
npx fqmpeg progress screen-pip.mp4 720 --pos top --color "red@0.7" --height 6
# → screen-pip-progress.mp4
# Step 3: 冒頭タイトル
npx fqmpeg text screen-pip-progress.mp4 "Vercel + Next.js のセットアップ" \
--pos center --font-size 64 --color white --bg "black@0.7" \
--start 0 --end 5
# → screen-pip-progress-text.mp4
ウェブカムが画面録画と違うアスペクト比(正方形ウェブカム vs 16:9 画面)の場合、pip のスケールはメイン側の寸法基準になる — 1920幅の画面に 0.2 指定なら、ウェブカム本体のサイズに関係なく384幅のオーバーレイになる。ウェブカムのアスペクトを保ちたい時は、事前に npx fqmpeg crop webcam.mp4 ... で整形してから pip に通す。
よくある質問
text の文字列にコロンやアポストロフィを入れたいときは?
そのまま入れて OK — npx fqmpeg text input.mp4 "Time: it's 12:34" で動く。fqmpeg のラッパーが : と ' を drawtext に埋め込む前にエスケープしてくれる(' → '\\\\''、: → \:)。シェル特殊文字(クオートやバッククオート)はシェル側のクオートで吸収するだけで他は何もいらない。
pip-grid に5本渡したら下の段が複製されたんだけど仕様?
仕様。入力本数がグリッドを埋めない時、空きスロットは「最後の入力」で埋められる。5本を 3x3(自動判定)に渡すと、スロット6-9 は入力5のクローン。4本で 2x2 を埋めたい(パディングをスキップしたい)なら、入力4本のまま渡す(自動で 2x2 が選ばれる)か --layout 2x2 で明示する。意図的に空白スロットを残したいなら、自分で黒画面動画を作って入力に混ぜる — fqmpeg は空きを合成してくれない。
progress に duration を毎回手で渡すのが面倒なんだけど?
FFmpeg の drawbox フィルタ式には「現在時刻 t」は使えるが「ソース総尺」を表す式が無い。fqmpeg はワークアラウンドとして duration を引数で受け取って式に焼き込んでいる。透過的に解決するなら ffprobe をラッパーから呼ぶ実装も可能だが、fqmpeg は単機能動詞の設計を保つために自動 probe はしない。実運用では dur=$(npx fqmpeg duration input.mp4) で取得して $dur を渡すワンライナーで十分。
watermark と picture の違いは?
watermark は既存の動画の上に静止画を重ねる — 入力は動画、ウォーターマークは小さい画像。picture はその逆で、静止画と音声トラックから動画を作る(音声の長さだけ画像をループ)。内部的には libavfilter の同じ仕組みを使っているが、解こうとしている問題が違う:ブランディング (watermark) vs 1枚画像動画化 (picture)。
histogram-overlay の位置や表示サイズは変えられる?
fqmpeg のフラグからは変えられない — どちらもハードコード(overlay=W-w-10:H-h-10 で右下マージン10px、size=320x240)。カスタムレイアウトが欲しいなら、--dry-run のフィルタ文字列をコピーして overlay=... と size=... を書き換えてから FFmpeg を直接叩く。よくある書き換え: 左下にしたければ overlay=10:H-h-10、大きいパネルなら size=480x270。
stack で「Input 1 height ... does not match」が出た
hstack は全入力の高さ一致が必須、vstack は幅一致が必須。違うほうを事前にリサイズする: npx fqmpeg resize smaller.mp4 --height 1080(もう一方の高さに合わせる)。アスペクト比が違ってクロップしたくない時は、pad で一旦次元を揃えてから stack する手もある — border を使うと装飾フレームで埋める形にできるので簡易の代替になる。
border で出力サイズが非標準になるのは大丈夫?
アスペクト比に厳しいプラットフォーム(Instagram の 1:1、YouTube Shorts の 9:16)では問題になる。1920x1080 に --width 30 で 1980x1140 になり、多くのプレイヤーはレターボックス、一部の SNS は再クロップする。回避策は2つ:(1) 先に crop で内側動画を縮めてから border で元サイズに戻す;(2) プラットフォーム任せにしてレターボックス or クロップを許容する。
複数オーバーレイ動詞をチェインすると H.264 の世代劣化が積もる?
各 fqmpeg 呼び出しが再エンコードを伴うので積もる。緩和策2つ:(1) 中間ステップを -crf 18 やロスレスに引き上げる(--dry-run 出力を編集);(2) fqmpeg を経由せず、各動詞の --dry-run から取ったフィルタ文字列を -vf "filter1,filter2,filter3"(複数入力を含むなら -filter_complex)で1コマンドにまとめる。2-3パスなら実コンテンツでほぼ気づかないレベル、5パス超えると見えてくる。
まとめ
C8 の13動詞は、編集後・最終出力前の合成オペレーションをカバーする:
- 静的グラフィック・テキスト (
watermark,text,drawbox,timecode,border) — ロゴ・タイトル・ハイライト・タイムスタンプ・装飾フレームの焼き付け - 複数動画の合成 (
pip,pip-grid,blend,stack) — ピクチャ・イン・ピクチャ、2-9入力グリッド、不透明度ブレンド、Before/After 並べ - 静止画→動画 (
picture) — 静止画 + 音声を再生可能な MP4 に - 解析オーバーレイ (
video-info-overlay,histogram-overlay,progress) — フレームメタ情報・カラースコープ・進捗バーをレビュー用に焼き付け
各動詞は --dry-run で内部の FFmpeg 呼び出しを表示するので、デフォルトが合わない時(histogram-overlay の位置をカスタムしたい、drawtext のフォーマットを変えたい、世代劣化を避けるため1パスでチェインしたい等)はコマンドをコピーして編集し、FFmpeg を直接叩くのが筋。fqmpeg 全体像は fqmpeg 完全ガイド を参照。