Python基于FFMPEG自动截图上传至imgbox(二)
本文最后更新于:2 年前
前言
话接上回,我么能够通过传递过来的视频文件路径获取视频长度和截图命令,那么如何使用python实现呢?
核心代码及思想
话不多说,上代码:
from pymediainfo import Mediainfo
def get_video_info(video_path) -> int:
"""
:return: 视频长度,数字
"""
media_info = MediaInfo.parse(video_path) # 解析视频
data = media_info.to_json()
data = json.loads(data)['tracks'] # 获取视频各种信息
for key in data:
if key['track_type'] == 'Video': # 视频的总帧数除以帧率得到长度
video_duration = int(key['frame_count']) / (int(key['frame_rate'].split('.')[0]))
return video_duration
上述代码可以直接得到一个视频的总的长度,但是我们想要截取图片的时候需要字符串,类似hh:mm:ss这样的。然后我们想要的是好几张图片?我以三张为例,假设一条线段想要有三个中间节点,那么我们会怎么处理呢?四等分就会有三个时间点了对不对?
比如60分钟的电影,我们取15分钟时间间隔,15, 30, 45 三个时间节点刚刚好,一般电影开头和截图截不出来什么东西的。我们需要把时间总长度4等分然后取三个节点将其转换成字符串传入截图函数中即可。
import subprocess
# 总的过程,传入一个时间长度,获取截图时间节点进行截图存储保存路径
def make_thumbnails(video_duration):
number = 3 # 截图张数
picture_list = [] # 用于存储截图的保存路径
seektime = 0 # 用于记录截图距离开头的时长,以秒计
interval = int(video_duration/(number+1)) # 计算时间间隔
for n in range(0, number):
seektime += interval # 计算时间节点
img = get_frame_at(seektime, n) # 截取对应时间节点的图片
if img:
picture_list.append(img)
return picture_list
# 被调用的函数,调用ffmpeg获取某一个时间节点的截图
def get_frame_at(seektime, n=99):
timestring = get_time_string(seektime) # 将int型转为hh:mm:ss类型用于截图
file_name = os.path.basename(video_path)
tmp_path = os.path.join(base_path, 'tmp') # 截图存放于事先新建的tmp目录下
img_path = os.path.join(tmp_path, "{filename}-out-{d}.png".format(filename=file_name, d=n)) # 截图名称及存放绝对路径
command = 'ffmpeg -ss {timestring} -y -i "{file}" "-f" "image2" "-frames:v" "1" "-c:v" "png" ' \
'"-loglevel" "8" "{img_path}"'.format(timestring=timestring, file=self.abs_file_path,
img_path=img_path)
try:
subprocess.call(command, shell=True)
return img_path
except Exception as exc:
logger.info('截图失败:%s' % exc)
return None
# 用于将int型转换为字符串的函数
def get_time_string(seconds) -> str:
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
seconds = int(seconds % 60)
timestring = str(hours) + ":" + str(minutes).rjust(2, '0') + ":" + str(seconds).rjust(2, '0')
return timestring
总结
是的,现在已经能够通过视频路径获取截图到指定目录了,但是怎么上传呢?国内外的图床很多都有着丰富的API,所以还需要使用一些模块来完成上传的工作。本例子使用imgbox作为目标图床。预知后事,请听下回分解。