压缩视频和图片 产生详情参考https://www.cnblogs.com/yoyo1216/p/12986050.html
import sys from PIL import Image import os import zlib import threading import platform class ZipPictureOrVideo(object): """ 压缩图片、视频 """ def __init__(self, filePath, inputName, resolution, bitrate, outName): self.filePath = filePath # 文件地址 self.inputName = inputName # 输入的文件名字 self.outName = outName # 输出的文件名字 self.resolution = resolution self.bitrate = bitrate self.system_ = platform.platform().split("-", 1)[0] if self.system_ == "Windows": self.filePath = (self.filePath + "\\") if self.filePath.rsplit("\\", 1)[-1] else self.filePath elif self.system_ == "Linux": self.filePath = (self.filePath + "/") if self.filePath.rsplit("/", 1)[-1] else self.filePath self.fileInputPath = self.filePath + inputName self.fileOutPath = self.filePath + outName @property def is_picture(self): """ 判断文件是否为图片 :return: """ picSuffixSet = {"BMP", "GIF", "JPEG", "TIFF", "PNG", "SVG", "PCX", "WMF", "EMF", "LIC", "EPS", "TGA", "JPG"} suffix = self.fileInputPath.rsplit(".", 1)[-1].upper() if suffix in picSuffixSet: return True else: return False @property def is_video(self): """ 判断文件是否为视频 :return: """ videoSuffixSet = {"WMV", "ASF", "ASX", "RM", "RMVB", "MP4", "3GP", "MOV", "M4V", "AVI", "DAT", "MKV", "FIV", "VOB", "WEBM"} suffix = self.fileInputPath.rsplit(".", 1)[-1].upper() if suffix in videoSuffixSet: return True else: return False def compress_picture(self): """ 压缩图片 :return: """ fpsize = os.path.getsize(self.fileInputPath) / 1024 # 获得图片多少K os.path.getsize(self.picPath)返回的是字节 if fpsize >= 50.0: # 是否大于50K im = Image.open(self.fileInputPath) # 打开图片 imBytes = im.tobytes() # 把图片转换成bytes流 imBytes = zlib.compress(imBytes, 5) # 对图像字节串进行压缩 im2 = Image.frombytes('RGB', im.size, zlib.decompress(imBytes)) # 压缩成新的图片 if self.outName: im2.save(self.fileOutPath) # 不覆盖原图 return (self.fileOutPath, os.path.getsize(self.fileOutPath)) else: im2.save(self.fileInputPath) # 覆盖原图 return (self.fileInputPath, os.path.getsize(self.fileInputPath)) else: return True def compress_video(self): """ 压缩视频 :return: """ fpsize = os.path.getsize(self.fileInputPath) / 1024 if fpsize >= 150.0: # 大于150KB的视频需要压缩 if self.outName: # 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( compress = "ffmpeg -i {} -b:v {}k -bufsize {}k -vf scale={} -minrate {}k -pix_fmt yuv420p -vcodec libx264 -preset veryslow -profile:v baseline -crf 23 {}".format( self.fileInputPath, self.bitrate, self.bitrate, self.resolution, int(self.bitrate) + 100, self.fileOutPath) print(compress) # sys.exit() isRun = os.system(compress) if isRun != 0: return (isRun, "没有安装ffmpeg,在Linux使用【apt install ffmpeg】安装,windows去【ffmpeg】官网下载") return True else: return True def start_compress_pic(self, is_async=True): """ 开始压缩图片 :param is_async: 是否为异步压缩,默认为TRue :return: """ if is_async: # 异步保存打开下面的代码,注释同步保存的代码 thr = threading.Thread(target=self.compress_picture) thr.start() else: # 下面为同步保存 self.compress_picture() def start_compress_video(self, is_async=True): """ 开始压缩视频 :param is_async: 是否为异步压缩,默认为TRue :return: """ if is_async: # 异步保存打开下面的代码,注释同步保存的代码 thr = threading.Thread(target=self.compress_video) thr.start() else: # 下面为同步代码 self.compress_video() if __name__ == "__main__": filePath = './input' # 文件地址 inputName = 'a.webm' # 输入文件名称 outName = 'd_b.mp4' # 输出文件名称 resolution = '960:540' # 分辨率 1920:1080 960:540 bitrate = 3000 # 码率 file = ZipPictureOrVideo(filePath, inputName, resolution, bitrate, outName) if file.is_picture: print(file.start_compress_pic()) elif file.is_video: print(file.start_compress_video()) else: print('该文件不是图片或者视频')