変換がしばらく進んだあと Too many packets buffered for output stream で中断する——。これは muxキュー(多重化キュー)の溢れ です。FFmpegは全ストリームが初期化されてインターリーブできるようになるまで、ある出力ストリームのパケットをバッファに溜めて待ちます。そのバッファが上限を超えると、ジョブが中断します。多くの場合フラグ1つで直り、なぜ起きるかを理解すれば、再エンコードのほうが綺麗な解決になる場面も分かります。本記事では両方を解説します。
動作確認: ffmpeg 8.1 で確認済み
この記事でわかること
- muxキューとは何か、なぜ溢れるのか
-max_muxing_queue_sizeで上限を引き上げる方法- 入力のインターリーブが悪いと、ストリームコピー時にこのエラーが起きる理由
- コピーではなく再エンコードすると根本的に直ることが多い理由
- 妥当なキューサイズの選び方
核心はこうです。コンテナはストリーム(映像・音声…)をおおむね時間順に交互配置(インターリーブ)して書き込みますが、muxは全出力ストリームが初期化されて初めて書き出しを開始できます。その間、FFmpegはすでに読み込んだ各ストリームのパケットを muxキュー に保持して待ちます。-max_muxing_queue_size はこのバッファが保持できるパケット数を決めます。あるストリームが、muxがまだインターリーブできる量を大きく超えてパケットを生み出すと、バッファが上限を超えて溢れ、FFmpegはこのエラーで停止します。
なぜ起きるのか
このエラーはほぼ必ず ストリームコピー(-c copy)中に現れます。FFmpegがパケットを手を加えずそのまま通すモードです。再エンコードしないためタイミングを調整できず、muxがインターリーブできる順番でパケットを渡さねばなりません。入力の インターリーブが悪い(例: 音声が来る前に映像パケットが延々と続く、タイムスタンプが飛ぶ)と、FFmpegは他方が追いつくのを待つ間、一方のストリームのパケットを読み続けてバッファします。遅れが十分大きいと、そのバッファが既定のmuxキューサイズを超えて溢れ、ジョブが失敗します。
要するに、これは破損ではなく、ストリーム同士と出力muxが期待するもののタイミング/インターリーブの不一致です。
解決策①: muxキューサイズを引き上げる
直接的な解決策は、-max_muxing_queue_size でmuxキューにより多くの余地を与えることです。これは 出力 オプションなので、出力ファイルの前に置きます。ストリームコピーでは -c copy のままキューだけ引き上げます。
ffmpeg -i input.mp4 -max_muxing_queue_size 1024 -c copy output.mp4
-max_muxing_queue_size 1024— muxキューで最大1024パケットまで待機を許可-c copy— ストリームはそのまま(無劣化・高速)に、バッファだけを拡大
キューが大きいほど実行中のメモリは増えますが、遅れたストリーム間のギャップを埋めるのに十分なパケットを保持できます。まず1024から始め、エラーが続く場合だけ上げてください。
コピーでキューを上げてもまだ失敗する場合は、再エンコードすれば解決することが多いです。デコードして再エンコードすると綺麗なインターリーブが再生成されます(解決策②)。大きめのキューと再エンコードを組み合わせると、しつこいケースの大半に対応できます。
ffmpeg -i input.mp4 -max_muxing_queue_size 4096 -c:v libx264 -c:a aac output.mp4
解決策②: コピーではなく再エンコードする
溢れは入力のインターリーブが原因なので、コピーではなく再エンコード すると、そのまま解決することがよくあります。FFmpegがデコードして再エンコードすると、タイムスタンプを再生成し、綺麗にインターリーブされた出力を書くため、muxが一方を待つ間にもう一方をバッファする必要がなくなります。
ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4
-c:v libx264— 映像を規則的なキーフレームとタイミングでH.264に再エンコード-c:a aac— 音声をAACに再エンコードし、映像と並べてインターリーブ
再エンコードせずどうしてもコピーが必要な場合(無劣化・高速を保ちたい)は、-c copy のまま解決策①の -max_muxing_queue_size に頼ってください。一度の変換による品質低下が許容できるなら、再エンコードがより確実な選択です。
まとめ
| 状況 | 対応 |
|---|---|
-c copy 中にエラー | 入力のインターリーブが悪く、バッファが溢れている |
| 最初の対処(無劣化を保つ) | 出力の前に -c copy と -max_muxing_queue_size 1024 を追加 |
| コピーでもまだ溢れる | キュー引き上げ+再エンコード:-max_muxing_queue_size 4096 -c:v libx264 -c:a aac |
| 完全に消したい | 再エンコード(-c:v libx264 -c:a aac)で綺麗なインターリーブを再生成 |
よくある質問
-max_muxing_queue_size はコマンドのどこに置きますか
出力オプションなので、入力の後・出力ファイルの前に置きます——例: ffmpeg -i input.mp4 -max_muxing_queue_size 1024 -c copy output.mp4。入力ではなく出力muxのキューを制御します。
キューサイズを大きくすると品質が落ちますか
落ちません。-max_muxing_queue_size はインターリーブ中にメモリへ保持できるパケット数を変えるだけです。エンコード品質には影響せず、溢れを防ぐだけです。トレードオフは実行中のメモリが少し増えることです。
なぜ -c copy は失敗するのに再エンコードは成功するのですか
-c copy ではFFmpegがタイミングを調整できないため、インターリーブの悪い入力では一方のストリームを大量にバッファせざるを得ません。再エンコードはタイムスタンプを再生成し、均等にインターリーブされた出力を作るので、深いバッファリングが不要になり、溢れを完全に回避できます。
最初はどの値から始めればよいですか
1024から始めてください。特にひどいファイルでエラーが続くなら4096に上げます。それより大きくする必要はめったになく、4096でも溢れるなら、再エンコード(解決策②)がより確実な道です。
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
動作確認: ffmpeg 8.1 (検証スクリプトで実行確認)
一次ソース: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-codecs.html