案例故事: 测试过程当中发现Bug视频, 须要提供给开发用于解Bug的参考,
可是视频拍摄后,太大且没法在微信客户端传输的问题,
因而乎出现过测试人员经过winzip分批压缩(part1, part2, part3),
再经过微信传输视频压缩包的"乱象":
做为测试总监,手底下的人这么"压缩视频“我是以为丢人的,
(1).视频文件已是二进制文件了,其实winzip已经压缩不了什么,
winzip压缩软件通常只适合压缩文本数据文件。
(2).视频压缩应该使用Video的编码技术实现二次编码压缩,业界最经常使用的确定是ffmpeg.exe工具。
还有好比当碰到一个Bug的视频太大了,没法做为附件上传到Bug系统,
会作视频压缩是合格的测试人员的必备能力之一,
本篇主要介绍如何经过ffmpeg 来实现批量压缩视频。python
视频文件是由视频流,音频流组成的将一系列图片快速播放产生的动态图像,音频的聚合体, 视频文件的音频流通常很是小,可是视频流很是大,视频流的大小主要取决于编码技术,分辨率,帧率这3个因素。
编程
编码技术Codec,是压缩多张图片的编码技术,好比多张图片组成的一个视频,
若是相连图片的像素相差不大,则只记录差别像素点便可,
从而实现了不影响画质的状况下,将视频文件最小化,
ffmpeg的默认的编码格式是:H.264, 其实还有不少编码格式,
好比Mpeg4, WMV10,H.263等等。微信
分辨率Resolution, 是视频每一帧(每张图片)的图片大小,是由一个一个像素点(pixel)组成的。ide
帧率是fps, 每秒钟的图片数,通常每秒4张图片以上(>4fps)就能够有明显的视频动画效果。函数
视频容器是Container, 是用于封装视频流,音频流的一个容器格式,通常有.mp4, .3gp, .avi, .mov等等。工具
比特率bitrate,是每秒钟的数据量,其数据量大小基本是受视频编码格式,分辨率,帧率3者因素影响的。测试
视频每作一次压缩,视频的数据量就会减小,且不可逆!
动画
ffmpeg的下载地址能够去:ffmpeg - 音视频图像编解码工具这篇文章查看。
视频压缩的经常使用命令模板是:
ffmpeg -i input.mp4 -s 640x480 -r 12 -y output.mp4
以上命令模板能够将input.mp4进行重编码(按帧率12fps,分辨率640x480),
并另存为output.mp4 , -y的意思是若是已经有这个文件,不询问直接覆盖。网站
若是要批量压缩视频,咱们仍是用输入输出模式,文件结构以下:编码
+---Input_Video #批量放入待压缩的视频 | 1.mp4 | 2.mp4 | +---Output_Video #批量输出已压缩的视频, 加一个后缀_c,表明以及转换完。 | 1_c.mp4 | 2_c.mp4 | \convert_video.py #Python视频转码脚本,双击运行便可
记住批处理脚本的精髓:批量顺序执行语句
# coding=utf-8 import os NEW_RESOLUTION = "640x480" # 目标分辨率,常量 NEW_FPS = 12 # 目标帧率,常量 curpath = os.getcwd() # 获取当前路径 input_dir = os.path.join(curpath, "Input_Video") output_dir = os.path.join(curpath, "Output_Video") input_video_list = os.listdir(input_dir) # 获取视频列表 # 若是没有Output_Video这个文件夹,则建立这个文件夹 if not os.path.exists(output_dir): os.mkdir(output_dir) # 开始批量二次编码压缩视频转码 for each_video in input_video_list: video_name, _ = os.path.splitext(each_video) # _是没意义,就只是一个无用代号,占个坑而已 ffmpeg_command = ("ffmpeg -i %s%s%s -s %s -r %s -y %s%s%s_c.mp4" % ( input_dir, os.sep, each_video, NEW_RESOLUTION, NEW_FPS, output_dir, os.sep, video_name)) print(ffmpeg_command) os.system(ffmpeg_command) os.system("pause")
面向过程函数的编程思惟应该是这样的:
你须要多少个功能(函数),才能作成这个事。
最好把功能(函数)都尽可能封装好,只暴露一些的参数接口便可。
# coding=utf-8 import os def convert_video(input_video_path, new_resolution, new_fps, output_video_path): ffmpeg_command = ("ffmpeg -i %s -s %s -r %s -y %s" % ( input_video_path, new_resolution, new_fps, output_video_path)) print(ffmpeg_command) os.system(ffmpeg_command) curpath = os.getcwd() # 获取当前路径 input_dir = os.path.join(curpath, "Input_Video") output_dir = os.path.join(curpath, "Output_Video") input_video_list = os.listdir(input_dir) # 获取视频列表 # 若是没有Output_Video这个文件夹,则建立这个文件夹 if not os.path.exists(output_dir): os.mkdir(output_dir) # 开始批量二次编码压缩视频转码 for each_video in input_video_list: video_name, _ = os.path.splitext(each_video) # _是没意义,就只是一个无用代号,占个坑而已 input_video_path = input_dir + os.sep + each_video output_video_path = output_dir + os.sep + video_name + "_c.mp4" convert_video(input_video_path, "640x480", "12", output_video_path) os.system("pause")
面向对象类的编程思惟应该是这样的:
若是给你一个空白的世界,在这个世界里你须要哪些种类的事物,
这些种类的事物都具有哪些共有的属性与方法,
这些种类(类)的事物(对象),和其余种类(其余类)的事物(其余对象)有什么关系。
尽可能把这些类封装好,只暴露对外的属性(变量)和方法(函数)便可。
# coding=utf-8 import os class VideoConverter(object): def __init__(self, input_video_path, new_resolution, new_fps, output_video_path): self.input_video_path = input_video_path self.new_resolution = new_resolution self.new_fps = new_fps self.output_video_path = output_video_path def convert_video(self): ffmpeg_command = ("ffmpeg -i %s -s %s -r %s -y %s" % ( self.input_video_path, self.new_resolution, self.new_fps, self.output_video_path)) print(ffmpeg_command) os.system(ffmpeg_command) if __name__ == '__main__': curpath = os.getcwd() # 获取当前路径 input_dir = os.path.join(curpath, "Input_Video") output_dir = os.path.join(curpath, "Output_Video") input_video_list = os.listdir(input_dir) # 获取视频列表 # 若是没有Output_Video这个文件夹,则建立这个文件夹 if not os.path.exists(output_dir): os.mkdir(output_dir) # 开始批量二次编码压缩视频转码 for each_video in input_video_list: video_name, _ = os.path.splitext(each_video) # _是没意义,就只是一个无用代号,占个坑而已 input_video_path = input_dir + os.sep + each_video output_video_path = output_dir + os.sep + video_name + "_c.mp4" v_obj = VideoConverter(input_video_path, "640x480", "12", output_video_path) v_obj.convert_video() os.system("pause")
包括:Input_Video(含一个H.264_1280x720_24fps.mp4视频),Python脚本
跳转至官网下载
武散人出品,请放心下载!
小提示以上3种形式,只是为了训练培养编程思惟,其实主要的核心代码就是ffmpeg命令那么一条,
若是不涉及批量处理,直接敲ffmpeg原始命令便可实现转码,
以上基本能够实现将100M的视频压缩到10M左右。
更多更好的原创文章,请访问官方网站:www.zipython.com
自拍教程(自动化测试Python教程,武散人编著)
原文连接:https://www.zipython.com/#/detail?id=52f5f5ed29a14614bc522754af3b7b4e
也可关注“武散人”微信订阅号,随时接受文章推送。