5

avconvを使用して、指定した時間にビデオ ファイルから 1 つの画像を取得したいと考えています。

libavについては、自分が何をしているのかを理解していると思うくらい読みましたが、実際に知るには十分ではありません。

私はもう試した:

avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -frames 1 output_image.jpg

t を使用して「frames」パラメーターを回避するだけでなく、

avconv -ss 00:00:01.786 -r 25 -i input_video.h264 -t 0.01 output_image.jpg

hh:mm:ss.xxx 形式を使用するのではなく、秒単位で渡します。

avconv -ss 1.786 -r 25 -i input_video.h264 -t 0.01 output_image.jpg

ss が 0 (「0」、「00:00:00.000」、「0.0」など) に設定されている場合、output_image はビデオの最初のフレームにすぎません。予想通り。

ss のその他の値 (0.0001 であっても) は、ビデオの最後のフレームを示します。

Raspbian wheezy リポジトリの最新の avconv を使用しています。この動作は私にはバグのように感じますが、ビデオ ストリーミングのその他の複雑な点につ​​いては、確信を持てるほどよく知りません。

誰かが私が間違っていることを知っていますか?



おまけの質問:実際には、同じビデオからこれらの画像を大量に取得したいと考えています。コマンドを一緒に文字列化することは、以前は機能していたようです。

avconv -ss 1.786 -r 25 -i input_video.h264 -t 0.01 output_image1.jpg 
-ss 3.454 -r 25 -i input_video.h264 -t 0.01 output_image2.jpg
-ss 5.823 -r 25 -i input_video.h264 -t 0.01 output_image3.jpg
-ss etc,etc.

しかし、この問題をデバッグするために単一の画像に切り替えました。最初の問題が解決されたと仮定すると、それがこのコマンドを構成する最良の方法ですか、それともより良い方法がありますか?

4

2 に答える 2

3

編集: Mulvyaが指摘したように、ffmpegは常に-ssで正確にシークします。この問題は avconv に限​​定されます。

-ssオプションの前にオプションを指定する-iと、avconv はフレーム位置を不正確に計算します。

最初にオプションを指定して-i、正しいタイムスタンプが正確に見つかるまでストリームを「シーク」する必要があることを avconv が認識できるようにする必要があります。

また、例の時間1.786は、例で指定した 1 秒あたりのフレーム数と一致していません-r 25

個々のフレームを正確に指定するには、 の任意1/25=0.04の値-ssが で割り切れる必要があるためです。0.04

以下は、ビデオの 46 番目のフレームを取得する必要があります。

avconv -i input_video.h264 -r 25 -ss 1.8 -frames:v 1 output_image.jpg

インデックスで特定のフレームを取得する場合は、次を使用する必要がありますbc

avconv -i input_video.h264 -r 25 -ss 0$(echo "scale=2;1000/25" | bc -l) -frames:v 1 output_image.jpg

1000ビデオの 1001 番目のフレームはどこにありますか (0/25最初のフレームであるため)。

@ hamboy75 の例とは異なり、-l(小文字の L)を渡しbcて、浮動小数点計算を実行する (最も近い整数に丸めない) ことに注意してください。scale=22 dp までの精度の数値を生成するために使用されます。

また、 avconv が理解できないbc先行ゼロなしで1未満の数値を出力する「機能」があることに注意してください。.04したがって、計算の先頭にゼロを挿入する必要もあります0$()

このコマンドを使用すると、次のような出力が得られます

frame=    0 fps=  0 q=0.0 size=       0kB time=10000000000.00 bitrate=   0.0kbit
frame=    0 fps=  0 q=0.0 size=       0kB time=10000000000.00 bitrate=   0.0kbit
frame=    0 fps=  0 q=0.0 size=       0kB time=10000000000.00 bitrate=   0.0kbit
frame=    0 fps=  0 q=0.0 size=       0kB time=10000000000.00 bitrate=   0.0kbit
frame=    0 fps=  0 q=0.0 size=       0kB time=10000000000.00 bitrate=   0.0kbit

これは、avconv が、要求した特定のフレームを正確に見つけるためにファイルをシークするためです。したがって、 avconv は常にストリームの先頭からストリームを「シーク」するため、インデックスが大きいフレームは抽出に時間がかかります。

したがって、フレームの範囲を抽出する方が望ましい場合があります。

avconv -i input_video.h264 -r 25 -ss 0$(echo "scale=2;7500/25" | bc -l) -t 0$(echo "scale=2;250/25" | bc -l) output_image_%04d.jpg

この例では、ビデオ内の 5 分間から 10 秒分のフレームを抽出します。もちろん、次を使用することもできます。

avconv -i input_video.h264 -r 25 -ss 300.0 -t 10.0 | bc -l) output_image_%04d.jpg

ただし、1 秒未満の継続時間の場合、値はビデオのフレーム レート (つまり0.0425 fps) で割り切れる必要があることに注意してください。

各フレームの画像には 、 、 などの名前が付けられoutput_image_0001.jpgますoutput_image_0002.jpg。抽出されたフレームで画像比較を実行する場合は、忠実度を高めるためにoverをoutput_image_0003.jpg使用することを検討してください。pngjpg

ビデオに存在するフレーム数よりも大きいフレーム インデックスを指定すると、avconv は検出した最後のフレームを単純に抽出することに注意してください。Duration:の出力の一部を見て、ビデオのフレーム数を計算したい場合がありavconv -i input_video.h264ます。

于 2016-03-04T11:01:53.177 に答える