次のコマンドがあります。
ffmpeg -f f32le -ar 44100 -channels 2 -i pipe:0 -ss 3 -i input.mp4 -y -f mp4 -map 0:a -map 1:v -c:v copy -use_editlist 0 output.mp4
ビデオストリームを再エンコードする代わりにコピーすると、ffprobe
から、ビデオストリームのシークされた位置を示す有用な情報を取得できません。
ストリーム全体で情報を収集してみました。
ffprobe -of json -show_streams -show_format output.mp4
ただし、start_time
は0
であり、期間は影響を受けません。また、ビデオストリームの最初のフレームで情報を収集してみました。
ffprobe -of json -select_streams v -show_frames output.mp4
まだ有用な情報はありません。
ただし、ビデオストリームを(コマンドから-c:v copy
を削除して)再エンコードすると、必要な情報が得られます。ビデオストリームの継続時間は、-ss
オプションによって変更されます。たとえば、ビデオの長さが5の場合、ffprobe
は2(5から3を引いた値)の長さを返します。これにより、シークされた位置がわかります。 -copyts
もミックスに投入すると、最初のフレームの情報を確認することで有用な情報を得ることができます。
ビデオストリームを再エンコードせずに、シークされた位置を取得するにはどうすればよいですか?乾杯!
元のファイルにアクセスし、使用したことがある場合
ffmpeg -f f32le -ar 44100 -channels 2 -i pipe:0 -ss X -i input.mp4 -y -f mp4 -map 0:a -map 1:v -c:v copy -use_editlist 0 output.mp4
次に、この方法に従います。
1)ソースビデオストリームの継続時間を取得する
ffprobe source.mp4 -show_entries stream=duration -select_streams v -of compact=p=0 -v 0
出力例:.
duration=229.033333
2)結果のビデオストリームの継続時間と最初のPTSを取得します
ffprobe output.mp4 -show_entries packet=pts_time:stream=duration -select_streams v -read_intervals 0%+#1 -of compact=p=0 -v 0
出力例:.
pts_time=0.066667
duration=220.700000
したがって、結果の最初のフレームは、ソースストリームの229.033333 - 220.700000
= 8.333333s
です。
ただし、-ss
がキーフレームを指していない可能性があるため、これは-ss値にはなりません。
3)、それで、最初のオーディオパケットの持続時間とPTSを取得します。 ffmpegは、指定された-ss
フレームとオーディオを同期するための時間を延長します。
ffprobe output.mp4 -show_entries packet=pts_time,duration_time -select_streams a -read_intervals 0%+#1 -of compact=p=0 -v 0
出力例:.
pts_time=0.000000|duration_time=2.733333
したがって、8.333333s + 2.733333 - 0.000000 - 0.066667
= 11.000000s
が求められるフレームです。