FFmpeg
是一款著名的开源音视频处理软件,它可以完成记录、转换数字音频、视频,并能将其转化为流等功能。
我们可以运用其强大的滤镜功能来完成一些对视频、音频的处理。而对于视频而言,如果只截取视频中的一帧图像,那么就可以完成对视频的截图。命令中可以使用-vframes
代替-frames:v
。
ffmpeg -ss HH:MM:SS -i input -frames:v 1 output
但事实上,FFmpeg
并不能截取对应时间准确的一帧。因为对于某些格式的视频而言,使用FFmpeg
的-ss
参数只能只能截取到欲截取帧前的关键帧。
如果想生成一个简单的缩略图,则需要使用一定数量的图片然后拼接起来。这里以3*3
的截图为例,那么我们所需要获取到的就是九张截图。如果想要等时间间隔的生成九张图片,那么我们首先要获取到的便是视频的时长。
ffprobe -i input -show_entries format=duration -v quiet -of csv="p=0"
Python
实现:import subprocess def get_length(video_name: str) -> str: cmd = 'ffprobe -i {} -show_entries format=duration -v quiet -of csv="p=0"'.format(video_name) result = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output, error = result.communicate() output = output.splitlines()[0] length = output.decode() return length
通过以上命令我们可以获得,以秒为单位的视频时长。所以我们可以把视频时长分成十份,然后用这九个间隔所在的点作为截图点。
def get_point(length: str) -> list:
length = int(float(length))
interval = length / (10)
time_list = []
# 生成截图时间点
for i in range(9):
time_list.append(interval * (i + 1))
return time_list
既然截图的时间点已经得到,那么我们就可以利用这些时间点来进行截图了。不过如果仅仅是将截图简单地获取并输出,那么我们就无法区分各个截图之间的区别。所以我们可以通过FFmpeg
的滤镜,在输出截图的同时将截图在视频中的时间点一并输出在截图上。
ffmpeg -start_at_zero -copyts -ss HH:MM:SS -i input \
-vf "drawtext=fontfile=./Arial.ttf:fontsize=20:fontcolor=yellow:x=5:y=5:text='Time\\: %{{pts\\:hms}}'" \
-vframes 1 output
在这段代码中,使用到的-start_at_zero
和-copyts
两个参数一般使用在视频截取中,保留原有的时间轴。-vf
即-filter:v
,drawtext
是视频滤镜的一种,用法可以查看这里。这里用以在图片左上角生成对应帧的时间戳。
import subprocess
import datetime
import shlex
def get_screenshot(video_name: str, time_list: list) -> list:
# 注意请将对应的字体文件放置于视频目录,避免出错。此处使用的是Arial字体。
ffmpeg_sh = '''ffmpeg -start_at_zero -copyts -ss {timestamp} -i {input} \
-vf "drawtext=fontfile=./Arial.ttf:fontsize=20:fontcolor=yellow:x=5:y=5:text='Time\\: %{{pts\\:hms}}'" \
-vframes 1 "{output}"'''
thumb_list = []
for i in time_list:
time = str(datetime.timedelta(seconds=i))
# 按现在时间生成截图名
time_now = str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S.%f"))
output_name = video_name + "_" + time_now
cmd = ffmpeg_sh.format(timestamp=time, input=video_name, output=output_name)
cmd = shlex.split(cmd)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
thumb_list.append(output_name)
while True:
if p.poll() is not None:
break
return thumb_list
通过以上代码我们就获取到了九张截图,以及九张截图的名字,接下来我们要做的就是将这九张截图组合成一张3*3
的截图。
本文由 admin 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Nov 15, 2019 at 09:18 pm