ライブキャプチャされたh.264ビデオを入力として受け取り、それをトリミングして、黒からフェードアップで開始し、エンコードをできるだけ少なくして黒にフェードアップして終了したいと思います。これらのフェードイン/フェードアウトポイントは、Iフレームの間にある場合があります。再エンコードせずに非Iフレームでトリミングすることはできません。
私は図を作りました:
入力ファイルを3つの部分に分割したいと思います。パートAはポイント1の前のIフレームで始まり、ポイント1で終わります。パートCはポイント2のIフレームで始まり、黒にフェードした後の次のIフレームで終わります。それらはすべてI-Frame形式に再エンコードされます。これらの2つのセグメントは、10〜30秒と比較的短くなります。パートB(ほとんどのビデオ)は、codec:copyを使用してトランスコードできます。
パーツAとCは(黒検出を使用して自動的に、または手動で)トリミングされ、次にビデオ全体がffmpegを使用して連結されます。
Ffmpegを使用したいのは、それが私が最もよく知っていることであり、ワークフローの残りの部分ではそれを排他的に使用しているためです。どのコマンドラインでこれを実現できますか?
好奇心旺盛な方のために、ライブビデオをエンコードされたセグメントにキャプチャするためのコマンドラインを次に示します。この時点から、不要なビデオを破棄し、トリミングに必要な場合はセグメントを再エンコードするのは簡単です。最後のステップは、セグメントを連結することです。
ffmpeg -f dshow -rtbufsize 702000k -video_size 1920x1080 -framerate 29.97 -pixel_format uyvy422 -i video="Decklink Video Capture":audio="Decklink Audio Capture" -threads 0 -c:v libx264 -s 1280x720 -crf 18 -profile:v main -level 3.1 -pix_fmt yuv420p -c:a libvo_aacenc -b:a 128k -ac 1 -f segment -segment_time 0.01 -reset_timestamps 1 seg%02d.mp4
これは、セグメントマルチプレクサと連結デマルチプレクサを使用して実現できます。
ステップ1入力をセグメント化します
キャプチャされたソースから00:50
を02:20
に抽出するとします。 GOPサイズが3秒だとしましょう。インポイントはGOPの最後のフレームである可能性があるため、1GOPの長さより早く開始する必要があります。したがって、トリムインは00:47
であり、抽出期間は01:33
です。そう、
ffmpeg -ss 0:57 -t 01:33 -i input.mp4 -c copy -f segment -segment_time 0.01 -reset_timestamps 1 seg%02d.mp4
これにより、それぞれがGOPの長さのセグメントが作成されます。したがって、これをコード内ストリームには使用しないでください:)
ステップ2頭と尾のセグメントをトリミングします
頭と尾の余分なセグメントを削除します-GOPの長さが短い場合に可能です。次に、正しいトップセグメントとテールセグメントをトリミングします。
ffmpeg -ss 2 -i seg00.mp4 -crf 18 -map [v] -map [a] seg00a.mp4
ffmpeg -t 2 -i seg46.mp4 -crf 18 -map [v] -map [a] seg46a.mp4
ステップ連結
a) concatファイルを準備しますsegments.txt
file 's00a.mp4'
file 's01.mp4'
file 's02.mp4'
...
file 's44.mp4'
file 's45.mp4'
file 's46a.mp4'
b)
ffmpeg -f concat -i segments.txt -c copy -fflags +genpts trimmed.mp4
ライブキャプチャで作業しているため、最終出力を除いて、MP4ではなくTSに出力できます。