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

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

元のファイルにアクセスでき、

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

関連情報