嗨,我需要使用ffmpeg的视频中提取帧..有一个更快的方式做到这一点比这个:
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
嗨,我需要使用ffmpeg的视频中提取帧..有一个更快的方式做到这一点比这个:
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
如果JPEG编码步骤过于性能密集型,你总是可以存储未压缩的BMP图像帧:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
这也有不被转码为JPEG招致通过量化更多的质量损失的优势。 (PNG也无损的,但往往需要更长的时间比JPEG编码。)
跨越这个问题就来了,所以这里是一个快速的比较。 比较这两种不同的方式来提取视频每分钟一帧38m07s长:
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
是默认的 ,并确保您添加-ss
输入视频前-i
选项。
请注意,最好使用-filter:v -fps=fps=...
而不是-r
因为后者可能是不准确的。 虽然门票被标记为固定的 ,我还是没遇到一些问题,所以更好地发挥它的安全。
如果你确切地知道哪些帧提取,例如1,200,400,600,800,1000,尝试使用:
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)' \
-vsync vfr -q:v 2
我用这一个管道ImageMagick的蒙太奇从任何视频10帧的预览。 显然,帧数你需要弄清楚使用ffprobe
ffmpeg -i myVideo.mov -vf \
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,100)',scale=320:-1 \
-vsync vfr -q:v 2 -f image2pipe -vcodec ppm - \
| montage -tile x1 -geometry "1x1+0+0<" -quality 100 -frame 1 - output.png
。
一点解释:
+
表示OR和*
为AND \,
简直就是逃避,
字符 -vsync vfr -q:v 2
似乎并没有工作,但我不知道为什么-任何人吗? 在我来说,我需要帧至少每秒。 我用上面的“寻求”的做法,但不知道如果我能并行任务。 我用FIFO方式的N个程序在这里: 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秒在我的情况。 唯一的问题是由于标准输出被淹没的主线程不会完全退出返回到终端。
我尝试过这个。 3600帧中32秒。 你的方法实在是太慢了。 你应该试试这个。
FFMPEG -i file.mpg -s 240x135 -vf FPS = 1%D.JPG