python压缩教程_《自拍教程66》Python ffmpeg批量压缩视频

案例故事: 测试过程中录制的Bug视频太大,导致无法在微信客户端传输,也无法作为附件上传到Bug系统问题,

曾经出现过测试人员通过winzip分批压缩(part1, part2, part3), 再通过微信传输视频压缩包的 " 高端操作 ":

作为测试总监,手底下的人这么"压缩视频“我是觉得丢人的,

(1).视频文件已经是二进制文件了,其实winzip已经压缩不了什么,

winzip压缩软件一般只适合压缩文本数据文件。

(2).视频压缩应该使用Video的编码技术实现二次编码压缩,业界最常用的肯定是ffmpeg.exe工具。

会做视频压缩是合格的测试人员的必备能力之一,

本篇主要介绍如何通过ffmpeg 来实现批量压缩视频。

视频的基本知识点

视频文件是由视频流,音频流组成的将一系列图片快速播放产生的动态图像,音频的聚合体, 视频文件的音频流一般非常小,但是视频流非常大,视频流的大小主要取决于编码技术,分辨率,帧率这3个因素。

编码技术Codec,是压缩多张图片的编码技术,比如多张图片组成的一个视频,

如果相连图片的像素相差不大,则只记录差异像素点即可,

从而实现了不影响画质的情况下,将视频文件最小化,

ffmpeg的默认的编码格式是:H.264, 其实还有很多编码格式,

比如Mpeg4, WMV10,H.263等等。

分辨率Resolution, 是视频每一帧(每张图片)的图片大小,是由一个一个像素点(pixel)组成的。

帧率是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视频转码脚本,双击运行即可

记得将ffmpeg.exe 丢到系统Path环境变量路径下去。

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")

Python面向过程函数形式

面向过程函数的编程思维应该是这样的:

你需要多少个功能(函数),才能做成这个事。

最好把功能(函数)都尽量封装好,只暴露一些的参数接口即可。

# 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")

Python面向对象类形式

面向对象类的编程思维应该是这样的:

如果给你一个空白的世界,在这个世界里你需要哪些种类的事物,

这些种类的事物都具备哪些共有的属性与方法,

这些种类(类)的事物(对象),和其他种类(其他类)的事物(其他对象)有什么关系。

尽量把这些类封装好,只暴露对外的属性(变量)和方法(函数)即可。

# 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左右。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值