「ループ」には 2 種類あります。同じ映像を頭から繰り返すリピートと、順再生の直後に逆再生をつなげて往復させるブーメラン(Instagram の Boomerang、往復 GIF)です。FFmpeg ではリピートは -stream_loop オプション 1 つ、ブーメランは reverse と concat の組み合わせで作れます。それぞれの書き方と、実際に作ったときのサイズ・処理時間を並べます。
動作確認: FFmpeg 8.1 / Windows — 本記事のコマンド 10 件を検証スクリプトで実行し、全て成功しました(2026-09-06)
リピート: -stream_loop(再エンコードなし)
ffmpeg -stream_loop 2 -i input.mp4 -c copy output.mp4
-stream_loop N は「追加で N 回繰り返す」なので、2 なら合計 3 周です。入力オプションなので必ず -i の前に書きます。後ろに書くと出力オプションと解釈されてエラーになります。
-c copy が使えるのがこの方法の最大の利点です。1080p 10 秒(30 MB)のクリップを 6 周・60 秒にしたところ、0.3 秒で終わりました。同じことを再エンコードで行うと 5.9 秒です(i9-14900KF、libx264 -preset veryfast -crf 23、2026-09-02 計測)。
指定した長さまでループさせる
-stream_loop -1 で無限ループにし、-t で出力を止めます。BGM の長さに合わせるときなどに便利です。
ffmpeg -stream_loop -1 -i input.mp4 -t 60 -c copy output.mp4
-t を忘れると永久に書き続けるので注意してください。
ループ動画に別の音声を付ける
短い映像を BGM の長さまで繰り返し、音声は別ファイルから取る構成です。-shortest で短いほう(この場合は BGM)が終わったところで止めます。
ffmpeg -stream_loop 3 -i input.mp4 -i bgm.mp3 -map 0:v -map 1:a -c:v copy -c:a aac -shortest output.mp4
映像を BGM より確実に長くしたいなら -stream_loop -1 にしておけば、-shortest が BGM の終端で全体を止めてくれます。
-c copy でループの継ぎ目がおかしいとき
-c copy のループは、元動画がキーフレームで始まり、タイムスタンプが 0 から始まっていることを前提にしています。スマホで撮ったままの MOV などで継ぎ目が飛んだり一瞬止まったりする場合は、一度 -c copy をやめて再エンコードするか、事前に -ss 0 -c copy で先頭を整えてください。
ブーメラン: 順再生 + 逆再生
split で映像を 2 系統に分け、片方を reverse で逆再生にし、concat で順→逆の順につなぎます。
ffmpeg -ss 2 -t 3 -i input.mp4 -filter_complex "[0:v]split[a][b];[b]reverse[r];[a][r]concat=n=2:v=1[v]" -map "[v]" -an -c:v libx264 -crf 20 -pix_fmt yuv420p -movflags +faststart output.mp4
-ss 2 -t 3— 2 秒地点から 3 秒間を切り出す。ブーメランは 1〜3 秒の素材が一般的で、reverseが全フレームをメモリに溜めるため長い素材は避けるべき(詳しくは逆再生の記事の実測表)split[a][b]— 同じ映像を 2 本に複製[b]reverse[r]— 片方を逆再生[a][r]concat=n=2:v=1[v]— 順 → 逆の順に結合(v=1は映像 1 本、音声なし)-an— 音声は捨てる。逆再生した音声はブーメランではまず使わない-movflags +faststart— Web 再生用に moov を先頭へ
3 秒の素材から 6 秒の往復動画ができます。1080p / 30fps でファイルサイズは 6.8 MB、処理時間 1.6 秒でした(-crf 20)。
音声も往復させる
必要なら音声側も同じ構造で asplit / areverse を使います。
ffmpeg -i input.mp4 -filter_complex "[0:v]split[a][b];[b]reverse[r];[a][r]concat=n=2:v=1[v];[0:a]asplit[c][d];[d]areverse[ar];[c][ar]concat=n=2:v=0:a=1[a]" -map "[v]" -map "[a]" -movflags +faststart output.mp4
往復を速くする
Boomerang らしいテンポにするには setpts で速度を上げます。concat の後ろに置きます。
ffmpeg -ss 2 -t 3 -i input.mp4 -filter_complex "[0:v]split[a][b];[b]reverse[r];[a][r]concat=n=2:v=1,setpts=0.5*PTS[v]" -map "[v]" -an output.mp4
往復を複数回繰り返す
一度作ったブーメランを -stream_loop で回すのが最も軽い方法です。
ffmpeg -stream_loop 2 -i boomerang.mp4 -c copy output.mp4
1 本のコマンドで済ませたいなら loop フィルタを concat の後ろに足します。loop=loop=2:size=32767:start=0 で全フレームを追加 2 回、計 3 往復です。
ffmpeg -ss 2 -t 3 -i input.mp4 -filter_complex "[0:v]split[a][b];[b]reverse[r];[a][r]concat=n=2:v=1,loop=loop=2:size=32767:start=0[v]" -map "[v]" -an output.mp4
size はバッファするフレーム数の上限で、フィルタの最大値 32767 を指定しています。loop フィルタも size 分のフレームをメモリに保持するので、-stream_loop が使える場面ではそちらを選んでください。どちらも 3 秒素材 × 3 往復 = 18 秒で、サイズは 20.3 MB(-stream_loop -c copy)と 20.8 MB(loop フィルタで再エンコード)でほぼ同じでした。
ブーメラン GIF
SNS やチャットに貼るなら GIF が求められることがあります。fps と scale で情報量を落とし、palettegen / paletteuse で 256 色に最適化します。
ffmpeg -ss 2 -t 2 -i input.mp4 -filter_complex "[0:v]fps=15,scale=480:-1,split[a][b];[b]reverse[r];[a][r]concat=n=2:v=1,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
-loop 0 は GIF の無限ループ指定(出力オプションなので -i の後)。-stream_loop とは別物です。
実測: GIF と MP4 のサイズ差
同じ 3 秒素材(1080p 30fps)から幅 480px / 15fps の 6 秒ブーメランを作った結果です。
| 形式 | サイズ | 処理時間 |
|---|---|---|
| GIF(palettegen / paletteuse、256 色) | 7.9 MB | 2.6 s |
MP4(libx264 -crf 23) |
0.3 MB | — |
26 倍の差です。GIF は 1 フレームごとに全ピクセルを持つ上に色が 256 に制限されるので、動きの多い実写ではこうなります。投稿先が MP4 を受け付けるなら(X、Discord、Slack、LINE はいずれも受け付けます)MP4 で出すべきで、GIF は「GIF しか貼れない場所」用と割り切ってください。GIF の画質・サイズ調整は GIF 作成 に詳しくまとめています。
一部区間だけを繰り返す(loop フィルタ)
動画の途中の特定フレーム区間だけを繰り返したいときは loop フィルタを使います。start に開始フレーム番号、size に繰り返す長さ(フレーム数)、loop に追加回数を指定します。
ffmpeg -i input.mp4 -vf "loop=loop=3:size=30:start=60" -an output.mp4
30fps なら「2 秒地点からの 1 秒間を追加で 3 回(計 4 回)繰り返す」という意味です。フレーム数指定なので、可変フレームレートの素材では狙った時刻とずれることがあります。
よくある質問
-stream_loop を付けたのに 1 回しか再生されない
-i の後ろに書いていないか確認してください。入力オプションなので -stream_loop 2 -i input.mp4 の順です。また、一部の形式(生 H.264 ストリームなど)ではシークできず無視されることがあります。MP4 / MKV / MOV では問題ありません。
ループのたびに一瞬止まる
-c copy の継ぎ目でタイムスタンプが不連続になっているのが原因です。再エンコード(-c:v libx264)するか、-fflags +genpts を付けて試してください。
ブーメランの折り返しで同じフレームが 2 回出る
concat で [a] の最終フレームと [r] の最初のフレーム(= 元の最終フレーム)が連続するためです。気になる場合は逆再生側の先頭を 1 フレーム落とします: [b]reverse,trim=start_frame=1[r]。
関連ツール
ループ・ブーメラン作成ツールは、この記事のブーメラン処理をブラウザ内で実行します。短いクリップ向けで、ファイルは端末から出ません。
関連記事
- 動画を逆再生にする —
reverseのメモリ消費の実測と対策 - GIF 作成 — パレット最適化とサイズ削減
- 動画を連結する(concat) — 別ファイル同士の結合
- 動画の再生速度を変える —
setptsの詳細