使用ffmpeg在间隔的第一帧每分钟生成缩略图

时间:2017-04-02 00:02:38

标签: bash video ffmpeg

当然,分钟可能不同(例如30秒或2分钟),但问题的逻辑仍然相同。我目前有三种解决方案,都有各自的缺点。

我的第一个解决方案使用fps选择如下:

ffmpeg -i <input> -vf scale=320:-1,fps=1/60 "img%04d.jpg"

这会经历一次视频,但是帧的选择不是每60秒的第一帧,而是它们的中间帧。这会在0:301:302:30等处生成帧,等等。

我的第二个解决方案通过bash计算缩略图的数量,并使用ss选项以手动搜索缩略图并检索它:

#durRaw: interval in seconds (this case: 60)
#end: the end index for the number of thumbnails needed
for t in $(seq 0 $end)
do
    local time=$(bc -l <<< "(( $t * $durRaw ))")
    ffmpeg -i <input> -ss $time -vframes 1 -vf scale=320:-1 "img$(printf "%04d" $t).jpg"
done

这会产生准确的帧,但视频读取次数太多,因为它通常需要搜索整个视频30-60次才能生成必要的缩略图。

最后,我的第三个解决方案恰好是快速而准确的,随着视频的进展质量下降(工件将开始变得可见,文件大小降低到可比文件的大约25%)。我知道视频是缩放的,但质量下降甚至比我缩放的还要大。我使用select过滤器并将帧速率计算输入其中:

getFrameRate() {
    ffmpeg -i "$1" 2>&1 | sed -n "s/.*, \(.*\) fp.*/\1/p"
}
local fr=$(getFrameRate <input>)
local sel=$(bc -l <<< "(( $fr * $durRaw ))") #in actual code, sel is floored
ffmpeg -i <input> -vf "scale=320:-1,select='not(mod(n,$sel))',setpts='N/($fr*TB)'" "img%04d.jpg"

enter image description here

如果没有某种大的缺点,我似乎无法生成缩略图。由于我需要通过的视频数量,解决方案2(虽然是最佳的)将花费数周来实际完成所需视频的处理。如果不涉及降级,解决方案3将是理想的,并且在线指南似乎都指向我尝试过的相同解决方案。简而言之,我需要能够合理地快速生成缩略图(也就是在单个直通中),而不会无理性地降低质量。

1 个答案:

答案 0 :(得分:0)

在输入(-ss)之前使用解决方案#2中的-i参数,以便更快地读取输入。作为摘录:

ss之前:

  

输入将使用关键帧解析,非常快

ss之后:

  

这里,输入将被解码(并被丢弃),直到它到达-ss给出的位置。这将非常慢地

完成

https://trac.ffmpeg.org/wiki/Seeking

花费时间从几分钟/小时到毫秒/秒生成信息。