实战使用HandBrake批量压缩视频

碎碎念

在使用handbrake之前我一直在尝试用大名鼎鼎的FFmpeg对视频进行压缩,可是却遇到不是压缩的太厉害导致视频模糊的看不清,就是视频压缩后反倒比之前大很多倍,不如不压缩,FFmpeg的参数多如牛毛,调来调去始终调不出来满意的参数搭配,无法在清晰度和文件大小之间达到一个平衡。

不过自从遇到了这篇博客的主角Handbrake之后,一切就迎刃而解了。Handbrake自带了很多preset预设,直接选一个比较成熟 的预设就可以,下面是本文所用到的完整命令:

./HandBrakeCLI -i 1.mp4 --preset "Social 100 MB 5 Minutes 1080p30" --optimize -o new.mp4

解释一下上述命令:

  • -i 意思是需要被压缩的原始视频的文件路径
  • –preset 这个就是我们的关键选项了,意思是压缩指标的预设,这里我们选择了“Social 100 MB 5 Minutes 1080p30”这个选项,这个选项是综合了视频清晰度和视频文件大小的最优项
  • –optimize 这个是web传输优化,开启后可以让视频在stream流媒体加载时更流畅,这个仅供参考,没有具体查过详细资料
  • -o 这个就是你压缩好的视频输出到哪里

为了方便大家的批量压缩,我写了一个Python脚本,如下:

# coding=utf-8

import os
import argparse
import subprocess
from pathlib import Path

def check_file_size(file_path):
    file_size = os.path.getsize(file_path)
    file_size =int(file_size/1024/1024)
    if file_size >= 100:
        return True
    else:
        return False

def get_videos_info_list(video_path, ext_name):
    file_list = []
    for root, _, files in os.walk(video_path):
        for file in files:
            if file.endswith(ext_name):
                file_list.append(root+"/"+file)
    return file_list

def main(video_path):
    current_path = Path.cwd()
    videos_list = get_videos_info_list(video_path, ".mp4")
    for v in videos_list:
        v_entity = os.path.split(os.path.abspath(v))
        v_abs_path = v_entity[0]
        v_filename_with_extension = v_entity[1]
        v_filename_without_extension = Path(v_filename_with_extension).stem
        v_file_extension = Path(v_filename_with_extension).suffix
        is_file_size = check_file_size(v)
        if is_file_size or '_new' in v_filename_with_extension:
            try:
                subprocess.check_call([str(current_path) + '/HandBrakeCLI','-i',v,
                                   '--preset','Social 100 MB 5 Minutes 1080p30',
                                   '--optimize','-o',
                                   v_abs_path + '/' + v_filename_without_extension + '_new' + v_file_extension])
            except subprocess.CalledProcessError:
                continue
            subprocess.check_call(['trash',v])




if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='A script to compress videos.')

    parser.add_argument(
        '-d', '--dir',
        help='the dir path which contains your videos',
        type=str)

    args = parser.parse_args()
    main(args.dir)

使用说明如下:

usage: handbrake_helper.py [-h] [-d DIR]

A script to compress videos.

optional arguments:
  -h, --help         show this help message and exit
  -d DIR, --dir DIR  the dir path which contains your videos

使用很简单,直接跟上你要批量压缩的视频的文件夹的绝对路径就可以了。

为了不误删大家的视频,上述脚本依赖了一个叫trash的命令,在Ubuntu和Mac OS下面的安装命令如下:

sudo apt install trash-cli
brew install trash-cli

安装完这个工具后,上述脚本在压缩完视频后就会把旧的占用空间很大的未被压缩的视频移动到一个你当前磁盘的垃圾目录了,你可以随时进去把你想恢复的视频恢复回来。