次のコマンドがあります:
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
、最初のフレームの情報をチェックして、有用な情報を取得できます。
ビデオ ストリームを再エンコードせずに、目的の位置を取得するにはどうすればよいでしょうか? よろしくお願いします!
答え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
求められるフレームです。