web-dev-qa-db-ja.com

FFprobe-ビデオストリームを再エンコードせずに「シーク位置」を取得することは可能ですか?

次のコマンドがあります。

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_time0であり、期間は影響を受けません。また、ビデオストリームの最初のフレームで情報を収集してみました。

ffprobe -of json -select_streams v -show_frames output.mp4

まだ有用な情報はありません。

ただし、ビデオストリームを(コマンドから-c:v copyを削除して)再エンコードすると、必要な情報が得られます。ビデオストリームの継続時間は、-ssオプションによって変更されます。たとえば、ビデオの長さが5の場合、ffprobeは2(5から3を引いた値)の長さを返します。これにより、シークされた位置がわかります。 -copytsもミックスに投入すると、最初のフレームの情報を確認することで有用な情報を得ることができます。

ビデオストリームを再エンコードせずに、シークされた位置を取得するにはどうすればよいですか?乾杯!

1
maximedupre

元のファイルにアクセスし、使用したことがある場合

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が求められるフレームです。

1
Gyan