「ループ」には 2 種類あります。同じ映像を頭から繰り返すリピートと、順再生の直後に逆再生をつなげて往復させるブーメラン(Instagram の Boomerang、往復 GIF)です。FFmpeg ではリピートは -stream_loop オプション 1 つ、ブーメランは reverseconcat の組み合わせで作れます。それぞれの書き方と、実際に作ったときのサイズ・処理時間を並べます。

動作確認: 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 が求められることがあります。fpsscale で情報量を落とし、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]

関連ツール

ループ・ブーメラン作成ツールは、この記事のブーメラン処理をブラウザ内で実行します。短いクリップ向けで、ファイルは端末から出ません。

関連記事