python 批量压缩手机视频

先安装ffmpeg

pip install ffmpeg-python -i https://pypi.tuna.tsinghua.edu.cn/simple

 

下面是代码,新建video_compress.py

import sys
import os
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor  # 线程池,进程池
# import zlib
import threading
# import platform
# from PIL import Image
import ffmpeg
from shutil import copyfile


def get_file_dir(file):
    """获取文件目录通用函数"""
    fullpath = os.path.abspath(os.path.realpath(file))
    return os.path.dirname(fullpath)


def SaveVideo(input_file):
    file_name = os.path.basename(input_file)
    arr = file_name.split('.')
    new_file_name = arr[0] + '_compress.' + arr[1]
    output_path = os.path.join(get_file_dir(input_file), 'compress_output')
    output_file = os.path.join(output_path, new_file_name)
    if not os.path.isdir(output_path):
        os.makedirs(output_path)
    if (os.path.exists(output_file)):
        print("已存在,跳过压缩")
        return
    # 执行probe执行
    probe = ffmpeg.probe(input_file)
    video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
    if video_stream is None:
        print('No video stream found', file=sys.stderr)
        return
        # sys.exit(1)
    # 宽度
    width = int(video_stream['width'])
    # # 高度
    height = int(video_stream['height'])
    # # 帧数
    # num_frames = int(video_stream['nb_frames'])
    # # 时长
    # time = (video_stream['duration'])
    # 比特率
    bitrate = (video_stream['bit_rate'])

    # print('width: {}'.format(width))
    # print('height: {}'.format(height))
    # print('num_frames: {}'.format(num_frames))
    # print('time: {}'.format(time))
    # print('bitrate: {}'.format(bitrate))
    if ((width == 720 and height == 1280) or (width == 1280 and height == 720)):
        if (int(bitrate) < 2500 * 1024):
            print("比特率过小,跳过压缩")
            try:
                copyfile(input_file, output_file)
            except IOError as e:
                print("Unable to copy file. %s" % e)
            return
    elif ((width == 1080 and height == 1920) or (width == 1920 and height == 1080)):
        if (int(bitrate) < 5000 * 1024):
            print("比特率过小,跳过压缩")
            try:
                copyfile(input_file, output_file)
            except IOError as e:
                print("Unable to copy file. %s" % e)
            return
    else:
        if (int(bitrate) < 2000 * 1024):
            print("比特率过小,跳过压缩")
            try:
                copyfile(input_file, output_file)
            except IOError as e:
                print("Unable to copy file. %s" % e)
            return

    fpsize = os.path.getsize(input_file) / 1024
    if fpsize >= 150.0:  # 大于150KB的视频需要压缩
        compress = "ffmpeg -i {} -r 25 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -crf 26 -profile:v baseline -acodec aac -b:a 96k -strict -2 {}".format(input_file, output_file)
        isRun = os.system(compress)
        # if outName:
        #     compress = "ffmpeg -i {} -r 25 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -crf 24 -profile:v baseline -acodec aac -b:a 128k -strict -2 {}".format(
        #         fileInputPath, fileOutPath)
        #     isRun = os.system(compress)
        # else:
        #     compress = "ffmpeg -i {} -r 10 -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline  -crf 23 -acodec aac -b:a 32k -strict -5 {}".format(self.fileInputPath, self.fileInputPath)
        #     isRun = os.system(compress)
        if isRun != 0:
            return (isRun, "没有安装ffmpeg")
        return True
    else:
        return True


def Compress_Video(self):
    # 异步保存打开下面的代码,注释同步保存的代码
    thr = threading.Thread(target=self.SaveVideo)
    thr.start()


def check_path(input_path):
    """如果输入的是文件则直接压缩,如果是文件夹则先遍历"""
    if os.path.isfile(input_path):
        SaveVideo(input_path)
    elif os.path.isdir(input_path):
        dirlist = os.walk(input_path)
        for root, dirs, files in dirlist:
            if (not (root.endswith("\\compress_output") or root.endswith("/compress_output"))):
                i = 0
                for filename in files:
                    i = i + 1
                    SaveVideo(os.path.join(root, filename))
                    # process_pool.submit(SaveVideo, os.path.join(root, filename))
                    # compress_by_tinypng(os.path.join(root, filename))
    else:
        print(u'目标文件(夹)不存在,请确认后重试。')


if __name__ == "__main__":
    process_pool = ProcessPoolExecutor(1)  # 定义5个进程
    b = sys.argv[1:]  # 测试压缩
    len_param = len(sys.argv)
    if len_param != 2:
        print('请使用: %s [inputpath] [outputpath]' %
              os.path.basename(sys.argv[0]))
    else:
        check_path(b[0])
        input("Press <enter> 请耐心等待\n")


-crf 控制视频输出质量,取值范围为0-51,0为无损,从主观上讲,18-28是一个合理的范围

 

最后执行命令 python video_compress.py /Users/xx/test 

如果要还原压缩后视频详细信息请参考 https://www.cnblogs.com/xiaocaidev/p/13617120.html

 

posted @ 2020-12-21 16:22  xiaocaidev  阅读(250)  评论(0编辑  收藏  举报