動画のループには2種類あります。同じ映像を頭から繰り返す「リピート」と、順再生のすぐ後に逆再生をつないで行き来させる「ブーメラン」(Instagram の Boomerang や往復 GIF)です。FFmpeg では、リピートは -stream_loop オプション1つで、ブーメランは reverse と concat の組み合わせで作れます。
リピート: -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 のループは、元の動画がキーフレームで始まっていることが前提です。スマホで撮ったままの MOV などで、つなぎ目が飛ぶときは、先に -c copy だけで MP4 に書き出し直し(ffmpeg -i input.mov -c copy fixed.mp4)、それをループさせてください。つなぎ目ごとに一瞬止まるときは、音声が映像より長くないか確認します(下の「よくある質問」)。
ブーメラン: 順再生 + 逆再生
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 で速度を上げます。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つのコマンドで済ませたいなら、concat の後ろに loop フィルタを足します。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 -c:v libx264 -crf 20 output.mp4
size はためておくフレーム数の上限で、ここではフィルタの最大値 32767 を指定しています。loop フィルタも、受け取ったフレーム(ここでは往復6秒の180フレーム)をメモリに持つので、-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 3 -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 は前のフレームと同じ画素を省くことしかできず、MP4 のように動きを予測して圧縮することができません。色も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 回しか再生されない
-stream_loop は、すぐ後ろの -i の入力にかかります。-i input.mp4 -stream_loop 2 -i bgm.mp3 のように書くと、繰り返されるのは bgm.mp3 で、input.mp4 は1回だけです。繰り返したい入力の前に、-stream_loop 2 -i input.mp4 の順で書きます。また、一部の形式(生の H.264 ストリームなど)では先頭に戻れず(シークできず)、無視されることがあります。MP4 でも、先頭がキーフレームで始まらないファイルは1回しか再生されません。その場合は -c copy で MP4 に書き出し直してからループさせます。
ループのたびに一瞬止まる
音声が映像より長いと、-stream_loop は長い音声に合わせて1周を数えるので、映像はつなぎ目ごとに最後のフレームで止まります。再エンコードや -fflags +genpts では直りません。音声がいらないなら、-an を付けてください。
ブーメランの折り返しで同じフレームが 2 回出る
concat で、[a] の最後のフレームと [r] の最初のフレーム(= 元の最後のフレーム)が続くためです。気になるときは、逆再生側の最初の1フレームを落とし、時刻を0から振り直します: [b]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[r]。setpts を付けないと、落とした1フレーム分の時間が空き、折り返し直前のフレームが2フレーム分表示されたままになります。
関連ツール
ループ・ブーメラン作成ツールは、上のブーメランの処理をブラウザの中で実行します。短いクリップ向けです。ファイルは端末の外に送られません。
関連記事
- 動画を逆再生にする —
reverseのメモリ消費の実測と対策 - GIF 作成 — パレット最適化とサイズ削減
- 動画を連結する(concat) — 別ファイル同士の結合
- 動画の再生速度を変える —
setptsの詳細