web-dev-qa-db-ja.com

FFmpegがビデオを分割して元に戻す

FFmpegを使用して、start_timeおよびend_time入力に基づいてビデオを分割し、それらを他のビデオファイルに置き換えようとしています。たとえば、入力10 15の場合、EXACT秒10 to 15を別の動画に置き換える必要があります。

OK。私の頭に浮かぶのはこれです:

  1. 最初にビデオを分割します(この場合、0-10、10-15、および15-end)
  2. 10-15を他のビデオに置き換える
  3. すべてのサブビデオをマージして戻す

最初の質問:これは最善かつ最速のソリューションですか?動画の特定の期間を別の動画に置き換えるための簡単なコマンドやその他のツールはありますか?

2番目の質問:FFmpegが実行可能なソリューションであると仮定して、単にffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4コマンドを使用すると、ビデオ処理コードがファイルを読み取って処理できません。私はmediainfoツールを使用して2つのファイルを比較し、ヘッダーサイズの違いに気付きましたが、ビデオコーデックに関連するものはすべて同じでした。 HEADER SIZEが異なるため、明らかに問題が発生していることに気づきました。ヘッダーサイズを強制する方法はありますか(コーデックを除く)同じですか?

更新:これは元の.mp4ファイルですエミュレータで正常に動作します。

8
Ariana

trimおよびconcatの使用–コーデックが異なるソースファイル

このため、個々のファイルが同じ解像度、理想的には同じフレームレートとクロマサブサンプリングなどであることを確認してください。これにより、連結中のエラーやグリッチを防ぐことができます。

trim および concat フィルターを使用して、ファイルを分割せずにすべてを一度に実行できます。

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

ここで、trimは、後で連結する入力ビデオストリーム(0:v1:v)の個々の部分を指定するために使用されます。これらのパーツには、v0v2という名前が付けられています。 (setptsフィルターは、これらの個々の部分のタイムスタンプを0にリセットします。これは連結に必要です)。その後、3つの部分を連結します。

特定のタイムスタンプから最後までトリミングする場合は、範囲を指定する代わりにtrim=start=15を使用します。

ファイルにオーディオがある場合は、これらのストリームを個別にトリミングする必要があります。

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

この場合、ビデオとオーディオは再エンコードされることに注意してください。適切な出力品質ターゲットを指定してください(例:-crf for x264、x265またはlibvpx-vp9)。これについての詳細は、FFmpeg Wikiで読むことができます。 VP9 または H.264 の場合。

個別のセグメントを使用する

クリップを分割して後で再構成する場合:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

ファイルに音声が含まれている場合は、上記と同じ方法を使用します。

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

これにより、ビデオストリームが再度エンコードされます。もう少し簡単ですが、それ以外の点では上記の方法と同等です。

concat demuxerの使用

原則として、concat demuxerを使用して、再エンコードせずにビットストリームを連結することもできます。 concat.txtというファイルを作成し、次のエントリを追加します(上記で作成したビデオクリップに対応)。

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

次に、これらの個々のファイルを連結します。

ffmpeg -f concat -i concat.txt -c copy output.avi

ただし、これには、クリップのコーデック、解像度、フレームレートなどが同じである必要があるため、あらゆる種類の異種ソースでは機能しません。

concatプロトコルの使用

上記の種類のファイルレベルの連結は、concatプロトコルを使用して、上記と同じ種類の制約(同じコーデック、解像度など)を使用しても実現できます。

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

連結の詳細については、 それぞれのFFmpeg Wikiページ を参照してください。

9
slhck