FFmpegを使用して、start_time
およびend_time
入力に基づいてビデオを分割し、それらを他のビデオファイルに置き換えようとしています。たとえば、入力10 15
の場合、EXACT秒10 to 15
を別の動画に置き換える必要があります。
OK。私の頭に浮かぶのはこれです:
最初の質問:これは最善かつ最速のソリューションですか?動画の特定の期間を別の動画に置き換えるための簡単なコマンドやその他のツールはありますか?
2番目の質問:FFmpegが実行可能なソリューションであると仮定して、単にffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4
コマンドを使用すると、ビデオ処理コードがファイルを読み取って処理できません。私はmediainfo
ツールを使用して2つのファイルを比較し、ヘッダーサイズの違いに気付きましたが、ビデオコーデックに関連するものはすべて同じでした。 HEADER SIZEが異なるため、明らかに問題が発生していることに気づきました。ヘッダーサイズを強制する方法はありますか(コーデックを除く)同じですか?
更新:これは元の.mp4
ファイルですエミュレータで正常に動作します。
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:v
、1:v
)の個々の部分を指定するために使用されます。これらのパーツには、v0
〜v2
という名前が付けられています。 (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ページ を参照してください。