[video] ffmpegを使ってフレームを抽出する最速の方法は?



Answers

この疑問を巡って来たので、ここで簡単に比較します。 38m07sのビデオから1分あたり1フレームを抽出するには、次の2つの方法を比較してください。

time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp

1m36.029s

これは、ffmpegがビデオファイル全体を解析して目的のフレームを取得するため、時間がかかります。

time for i in {0..39} ; do ffmpeg -accurate_seek -ss `echo $i*60.0 | bc` -i input.mp4   -frames:v 1 period_down_$i.bmp ; done

0m4.689s

これは約20倍高速です。 高速サーチを使用して、目的の時間インデックスに移動し、フレームを抽出した後、時間インデックスごとにffmpegを数回呼び出します。 -accurate_seek がデフォルトであり、入力video -iオプションの前に-ssを必ず追加してください。

-filter:v -fps=fps=...を使用する方が良いことに注意してください。後者が不正確である可能性があるため-r代わりに-filter:v -fps=fps=... が使用されます。 チケットは固定されているとマークされていますが 、私はまだいくつかの問題を経験しています。

Question

こんにちは、私はffmpegを使用してビデオからフレームを抽出する必要があります..これよりも速い方法がありますか:

ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg




私の場合、少なくとも毎秒フレームが必要です。 私は上記のアプローチを採用しましたが、タスクを並列化できるかどうか疑問に思っていました。 私はFIFOアプローチでN個のプロセスを使用しました: https://unix.stackexchange.com/questions/103920/parallelize-a-bash-for-loop/216475#216475 : https://unix.stackexchange.com/questions/103920/parallelize-a-bash-for-loop/216475#216475

open_sem(){
mkfifo /tmp/pipe-$$
exec 3<>/tmp/pipe-$$
rm /tmp/pipe-$$
local i=$1
for((;i>0;i--)); do
    printf %s 000 >&3
done
}
run_with_lock(){
    local x
    read -u 3 -n 3 x && ((0==x)) || exit $x
    (
    "$@" 
    printf '%.3d' $? >&3
    )&
}
N=16
open_sem $N
time for i in {0..39} ; do run_with_lock ffmpeg -ss `echo $i` -i /tmp/input/GOPR1456.MP4  -frames:v 1 /tmp/output/period_down_$i.jpg  & done

基本的に私は&を使ってプロセスをフォークしましたが、同時スレッドの数はNに制限されていました。

これは私の場合26秒から16秒にアプローチを改善しました。 唯一の問題は、stdoutがフラッディングされているので、メインスレッドが端末にきれいに戻ることができないことです。






Related



Tags

video   ffmpeg