FFMPEG生成N个均匀间隔的PNG屏幕截图

FFMPEG生成N个均匀间隔的PNG屏幕截图,ffmpeg,Ffmpeg,我正在尝试使用FFMPEG为上传的视频生成8个屏幕截图。我目前有: ffmpeg-i预告片-720p.mov-r.2 -vcodec png预览-%d.png 每5秒生成一个屏幕截图。我如何才能添加为分布在总时间百分比上的帧生成屏幕截图的功能。谢谢此外,是否可以生成50%的屏幕截图?谢谢。如果您仅使用-i参数运行ffmpeg,它将为您提供stderr上视频的长度(以及许多其他内容)。您可以写一些关于这方面的东西,将持续时间和预期帧数转换为正确的-r参数 下面是python中的一个快速示例,它基本

我正在尝试使用FFMPEG为上传的视频生成8个屏幕截图。我目前有:

ffmpeg-i预告片-720p.mov-r.2 -vcodec png预览-%d.png


每5秒生成一个屏幕截图。我如何才能添加为分布在总时间百分比上的帧生成屏幕截图的功能。谢谢此外,是否可以生成50%的屏幕截图?谢谢。

如果您仅使用-i参数运行ffmpeg,它将为您提供stderr上视频的长度(以及许多其他内容)。您可以写一些关于这方面的东西,将持续时间和预期帧数转换为正确的-r参数

下面是python中的一个快速示例,它基本上实现了我所描述的功能。出于某种原因,由我的ffmpeg版本生成的前两个剧照都显示第0帧,但Preview-3到Preview-n的间隔是正确的。在第二个参数设置为“1”的情况下运行它,它将生成中间帧Preview-3.png

#!/usr/bin/env python

import sys,os,re
from subprocess import *

if len(sys.argv)<=1:
  print("usage: python oneinn.py filename frames")
  sys.exit(0)

try:
  fvideo = sys.argv[1]
  frames = float(sys.argv[2])
except:
  sys.stderr.write("Failed to parse parameters.\n")
  sys.exit(1)

output = Popen(["ffmpeg", "-i", fvideo], stderr=PIPE).communicate()

# searching and parsing "Duration: 00:05:24.13," from ffmpeg stderr, ignoring the centiseconds
re_duration = re.compile("Duration: (.*?)\.")
duration = re_duration.search(output[1]).groups()[0]

seconds = reduce(lambda x,y:x*60+y,map(int,duration.split(":")))
rate = frames/seconds

print("Duration = %s (%i seconds)" % (duration, seconds))
print("Capturing one frame every %.1f seconds" % (1/rate))

output = Popen(["ffmpeg", "-i", fvideo, "-r", str(rate), "-vcodec", "png", 'Preview-%d.png']).communicate()
#/usr/bin/env python
导入系统、操作系统、re
从子流程导入*
如果len(sys.argv)在Ruby中有一个:

或者只使用shell命令:

ffmpeg-i input.m4v-vf fps=1/$(echo'scale=6;'$(ffprobe-loglevel) 安静-属于'compact=nokey=1:print\u section=0'-显示格式\u条目 持续时间输入.m4v)“/10'| bc)-vframes 10-qscale:v2 缩略图-%d.png


这将创建10个与源视频尺寸相同的缩略图。

我无法让Manfred Stienstra的精彩oneliner在正确的位置生成帧。如果我指定从一部240秒的电影中生成8张图像,第一张是15张,第二张是45张,等等。我希望第一个是0,第二个是30,等等

所以我把他的一行拆开,创造了这个

ffmpeg=../bin/ffmpeg
ffprobe=../bin/ffprobe
outdir=../test
infile=../testmovie.mp4
outbase=testmovie

steps=8

len=`$ffprobe -loglevel quiet -of 'compact=nokey=1:print_section=0' -show_format_entry duration $infile`
echo length $len

secs=`echo 'scale=6;' $len ' /  ' $steps | bc`
echo secs $secs

for ((i=0; i <= $steps ; i++)); do
    echo =========================
    echo $ffmpeg -nostats -loglevel 0 \
            -i $infile -f image2 -ss `echo $secs \* $i | bc` \
             -vframes 1 "$outdir/$outbase"-$i.jpg
    $ffmpeg -nostats -loglevel 0 \
            -i $infile -f image2 -ss `echo $secs \* $i | bc`  \
             -vframes 1 "$outdir/$outbase"-$i.jpg
done
ffmpeg=../bin/ffmpeg
ffprobe=../bin/ffprobe
outdir=../test
infle=../testmovie.mp4
outbase=testmovie
步骤=8
len=`$ffprobe-loglevelquiet-of'compact=nokey=1:print\u section=0'-show\u format\u条目持续时间$infle`
回声长度$len
秒='echo'标度=6;'$len'/'$steps | bc`
回声秒$秒

对于((i=0;谢谢。我想在FFMPEG中完成这一切(我正在使用不允许脚本的外部服务),但我非常感谢你的回答。在打印调用后添加括号,使其与python3兼容。回答非常好!非常棒。bc使用ffprobe计算fps秒数。
scale=6
是该数字中使用的位数。
qscale:v
是可变比特率,设置为2。我不知道为什么
vframes 10
是空的这里。具有FPS(1/帧间隔)的视频过滤器应产生具有正确帧数的流,但有时由于舍入,我们会关闭一个。-vframes硬限制帧数(即有时丢弃最后一帧).正确,我故意跳过第一帧。根据我的经验,这一帧通常不是很有趣,因为它是黑色的,是标题屏幕的开始,或是有人在准备演示等。在我们的软件中,我们也默认为第三个缩略图,因为这通常是动作发生的地方。
ffmpeg=../bin/ffmpeg
ffprobe=../bin/ffprobe
outdir=../test
infile=../testmovie.mp4
outbase=testmovie

steps=8

len=`$ffprobe -loglevel quiet -of 'compact=nokey=1:print_section=0' -show_format_entry duration $infile`
echo length $len

secs=`echo 'scale=6;' $len ' /  ' $steps | bc`
echo secs $secs

for ((i=0; i <= $steps ; i++)); do
    echo =========================
    echo $ffmpeg -nostats -loglevel 0 \
            -i $infile -f image2 -ss `echo $secs \* $i | bc` \
             -vframes 1 "$outdir/$outbase"-$i.jpg
    $ffmpeg -nostats -loglevel 0 \
            -i $infile -f image2 -ss `echo $secs \* $i | bc`  \
             -vframes 1 "$outdir/$outbase"-$i.jpg
done