ffmpegを使用して、ビデオファイルから画像を正確にエクスポートするにはどうすればよいですか?


4

私の目標; ffmpegを使用して、ビデオファイルから一連の画像をエクスポートします。私の問題は1秒あたりのフレーム数とビットレートに関連していると思います。

次のコマンドを試しました。 ffmpeg -i myVideo.mp4 -r 1 images_%04d.jpg しかし、どういうわけか45秒のビデオで、47枚の画像になってしまいました。これを正確に把握することは非常に重要です。適切なFPSまたはビットレートが何であるかを事前に知ることはできません。コマンドの実行時にこれらの値が必要な場合は、ffmpegから何らかの方法でそれらを取得できる必要があります。

また、ビデオのすべての画像をエクスポートし、画像ffmpeg -i myVideo images_%04d.jpgの数をビデオの合計秒数で割ることも検討しました。これにより、24.97のようになり、25に丸めて、25フレームごとに24を削除します。私の恐れは、ファイルがVBRであり、高ビットレート部分がビデオの先頭にある場合、終了するフレームが1秒あたり1つと正確に一致しないことです。たとえば、30番目の画像が実際に2番目の31に近いビデオに表示される場合があります。

 ffmpegの実行-> ffmpeg -i "/videos/11.mp4" -s "352x264" "/images/image%06d.jpg"
FFmpegバージョン0.6-4:0.6-2ubuntu6.1、著作権(c)2000-2010 FFmpeg開発者
  2011年3月31日18:43:47にgcc 4.4.5で構築
  設定:--extra-version = 4:0.6-2ubuntu6.1 --prefix = / usr --enable-avfilter --enable-avfilter-lavf 
--enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex 
--enable-libtheora --enable-libvorbis --enable-vaapi --enable-pthreads --enable-zlib --enable-libvpx 
--disable-stripping --enable-runtime-cpudetect --enable-gpl --enable-postproc --enable-x11grab 
--enable-libdc1394 --enable-shared --disable-static
  libavutil 50.15。1 / 50.15。1
  libavcodec 52.72。2 / 52.72。2
  libavformat 52.64。2 / 52.64。2
  libavdevice 52. 2. 0 / 52. 2. 0
  libavfilter 1.19。0 / 1.19。0
  libswscale 0.11。0 / 0.11。0
  libpostproc 51. 2. 0 / 51. 2. 0

ストリーム1コーデックフレームレートがコンテナフレームレートと異なるようです:49938.00(49938/1)-> 24.97(24969/1000)
「/videos/11.mp4」から#0、mov、mp4、m4a、3gp、3g2、mj2を入力します。
  メタデータ:
    major_brand:mp42
    minor_version:0
    compatible_brands:isomavc1mp42
  期間:00:00:32.60、開始:0.000000、ビットレート:433 kb / s
    ストリーム#0.0(und):オーディオ:aac、44100 Hz、ステレオ、s16、127 kb / s
    ストリーム#0.1(und):ビデオ:h264、yuv420p、352x264 [PAR 1:1 DAR 4:3]、303 kb / s、24.97 fps、24.97 tbr、24969 tbn、49938 tbc
#0、image2を「/images/image%06d.jpg」に出力します。
  メタデータ:
    エンコーダー:Lavf52.64.2
    ストリーム#0.0(und):ビデオ:mjpeg、yuvj420p、352x264 [PAR 1:1 DAR 4:3]、q = 2-31、200 kb / s、90k tbn、24.97 tbc
ストリームマッピング:
  ストリーム#0.1->#0.0
[q]を押してエンコードを停止しますframe = 176 fps = 0 q = 24.8 size = -0kB time = 7.05 bitrate =  
-0.0kbits / s ^ Mframe = 312 fps = 236 q = 24.8 size = -0kB time = 12.50 bitrate = -0.0kbits / s    
^ Mframe = 316 fps = 112 q = 24.8 size = -0kB time = 12.66 bitrate = -0.0kbits / s ^ Mframe = 322 
fps = 55 q = 24.8 size = -0kB time = 12.90 bitrate = -0.0kbits / s ^ Mframe = 327 fps = 39 q = 24.8 
size = -0kB time = 13.10 bitrate = -0.0kbits / s ^ Mframe = 331 fps = 33 q = 24.8 size =      
-0kB time = 13.26 bitrate = -0.0kbits / s ^ Mframe = 336 fps = 31 q = 24.8 size = -0kB time = 13.46 
ビットレート= -0.0kbits / s ^ Mframe = 339 fps = 27 q = 24.8 size = -0kB 
time = 13.58 bitrate = -0.0kbits / s ^ Mframe = 344 fps = 22 q = 24.8 size = -0kB 
時間= 13.78ビットレート= -0.0kbits / s 

誰もffmpegでビデオから画像をエクスポートする時間精度の結果を得る方法のアイデアを持っていますか?? ありがとう!


ビデオコーデックとは何ですか?
スティーブンペニー

1
関連する可能性があります... FFmpegバージョンを必ず更新してください
-slhck

回答:


1

フレームを失っていますか?入力ビデオは可変フレームレートをサポートするh264です。各フレームの詳細を取得するには、次を使用することをお勧めします。

ffmpeg -i inputvideo -vf showinfo -acodec copy -vcodec mpeg2video temp.mp4

これにより、ムービーのフレーム数がわかります。

-r float引数を使用してムービーを非可変フレームレートビデオに変換してから、コマンドで行ったように写真をエクスポートすることにより、可変フレームレートを回避できます。


1

手動で-vsync値を指定する必要があります。不一致は、可変/一定のフレームレートとフレームタイムスタンプの違いが原因である可能性があります。VFRソースがある場合、ffmpegはデフォルトで推定レート(tbr値)をターゲットとし、モーションを「スムーズ」にするためにフレームをドロップまたは複製します。フレームを画像としてエクスポートする場合も、この動作に従います。ドキュメントからの情報:

-vsync パラメーター

ビデオ同期方法。互換性の理由から、古い値は数値として指定できます。新しく追加される値は、常に文字列として指定する必要があります。

0、パススルー

各フレームは、そのタイムスタンプとともにデマルチプレクサからマルチプレクサに渡されます。

1、CFR

要求された一定のフレームレートを正確に達成するために、フレームが複製およびドロップされます。

2、vfr

フレームは、2つのフレームが同じタイムスタンプを持つことを防ぐために、タイムスタンプとともにパススルーされるか、ドロップされます。

ドロップ

パススルーとしてすべてのタイムスタンプを破棄します。これにより、マルチプレクサはフレームレートに基づいて新しいタイムスタンプを生成します。

-1、自動

マルチプレクサの機能に応じて1〜2を選択します。これがデフォルトの方法です。

ここで言うように、ffmpegは-vsync -1デフォルトで選択します(ビデオエンコーディングと画像エクスポートの両方)。必要なのは、変更のないストレートパススルーです。-vsync 0すべてのフレームをドロップやデュペなしでそのまま保持する場合に使用します。おそらく、単調でないDTSに関するメッセージが表示されますが、これはほとんど無視できます。ビデオからすべてのフレームを正確に出力するためのコマンドの例を次に示します。

ffmpeg -i video.nut -f image2 -vsync 0 frame-%03d.tiff

0

-r引数を使用して画像を抽出すると、同様の不規則な動作が見られます。

代わりに-vf fps = Xオプションを使用することで解決できる解決策を見つけました(以下の重要な注意事項を使用)。信じられないかもしれませんが、ここでの動作は-rを使用した動作よりも予測可能です。

  1. 入力ビデオからX秒ごとに画像を生成するには、1 / Xの浮動小数点値を計算して実行します。

ffmpeg -i input.mp4 -vf fps=1.0/x image-%04d.jpg

たとえば、1秒間に2つの画像を取得するには:

ffmpeg -i input.mp4 fps=0.5 image-%04d.jpg

これはほぼ正しいことを行います。

  1. 余分な最初のフレームが生成されますが、これは無視する必要があります。
  2. フレームはX秒ごとに作成されます。ここで、Xは-vf fps=XX / 2秒から始まるの引数です。

だから、実行:

ffmpeg -i input.mp4 fps=1 image-%04d.jpg

5秒のビデオでは6つのファイルが作成され、最初のファイルは無視され、2番目から6番目はタイムスタンプ0.5、1.5、2.5、3.5、4.5に対応します。

この種のことをデバッグするための便利なテストビデオを次に示します。

https://drive.google.com/file/d/0B56RokrDs3xabS1TS19wRjlBaVk/view?usp=sharing

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.