Python基于FFMPEG自动截图上传至imgbox(二)

本文最后更新于:1 年前

前言


话接上回,我么能够通过传递过来的视频文件路径获取视频长度和截图命令,那么如何使用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作为目标图床。预知后事,请听下回分解。



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!