一个基于 Python 和 FFmpeg 的视频批量压缩工具,支持 H.264/HEVC/AV1 三种主流编码格式,内置便携版 FFmpeg,无需手动安装,支持 GPU 硬件加速编码。
- ✅ 批量处理:支持批量压缩多个视频文件
- ✅ 多格式支持:支持 MP4、MKV、AVI、MOV、FLV、WebM、WMV、M4V 等主流视频格式
- ✅ 递归处理:可选择是否递归处理子目录中的视频文件
- ✅ 灵活输出:支持自定义输出目录或保存在源文件同目录(自动添加
_compressed后缀) - ✅ 码率可调:自由设置目标视频码率(如 500K、1M、2M 等)
- ✅ CRF 模式:支持恒定质量因子(CRF)编码,智能预估压缩收益
- ✅ 智能采样:CRF 模式下自动进行多点采样预估,避免无效转码
- ✅ 智能检测:自动跳过原始码率低于目标的视频,避免不必要的处理
- ✅ 跳过文件复制:可选择将跳过的视频复制到输出目录,保持输出目录完整性
- ✅ 音频保持:自动检测并保持原始音频码率
- ✅ 进度显示:实时显示处理进度条(已用时间/剩余时间/处理速度)
- ✅ GPU 加速:自动检测并使用 NVIDIA/Intel/AMD GPU 进行硬件加速编码
- ✅ 便携部署:首次运行自动下载 FFmpeg,无需手动安装配置
- ✅ 多编码支持:支持 H.264、HEVC (H.265)、AV1 三种编码格式
- ✅ 文件存在检测:自动跳过已存在的输出文件,支持断点续传
- ✅ 中断保护:用户中断时自动清理临时文件
- Python 3.7+
- Windows / Linux / macOS
- 网络连接(用于首次下载 FFmpeg)
- NVIDIA/Intel/AMD GPU(可选,用于硬件加速)
bash
pip install -r requirements.txt
依赖说明:
ffmpeg-python>=0.2.0:Python 操作的 FFmpeg 绑定库urllib3>=1.26.0:用于下载 FFmpegtqdm>=4.65.0:用于显示进度条
bash
python main.py -i <输入目录> [-o <输出目录>] [-b <目标码率>] [-r] [--cpu] [--codec h264|hevc|av1] [-c]
💡 提示:首次运行时会自动下载 FFmpeg(约 30-50MB),请耐心等待下载完成。
| 参数 | 简写 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|
--input-dir |
-i |
是 | - | 输入视频目录路径 |
--output-dir |
-o |
否 | 源文件同目录 | 输出目录路径 |
--bitrate |
-b |
否 | 1000K | 目标视频码率(如:500K, 1M, 2M) |
--recursive |
-r |
否 | False | 是否递归处理子目录 |
--cpu |
- | 否 | False | 强制使用 CPU 编码,不使用 GPU 加速 |
--codec |
- | 否 | h264 | 视频编码格式:h264(兼容性好)、hevc(高效)、av1(最新最高效) |
--copy-skipped |
-c |
否 | False | 将跳过的视频复制到输出目录 |
--crf |
- | 否 | None | CRF值(0-51),启用CRF模式。推荐:H.264(18-28), HEVC(20-30), AV1(25-35) |
--min-benefit |
- | 否 | -10.0 | CRF采样预估的最小收益阈值(百分比,默认-10%)。负值表示允许文件略微增大以尝试压缩,实际压缩后会检测文件大小,只有更小时才采用 |
--max-samples |
- | 否 | 5 | CRF采样预估的最大采样点数 |
bash
python main.py -i ./videos
输出文件将保存在源文件同目录,文件名添加 _compressed 后缀。
bash
python main.py -i ./videos -o ./output -b 800K --codec hevc
使用 HEVC 编码将视频压缩为 800K 码率,并保存到 output 目录。
bash
python main.py -i ./videos -o ./output -b 600K --codec av1 -r
使用 AV1 编码递归处理 videos 目录下所有子目录中的视频文件。
bash
python main.py -i ./videos -b 1000K --cpu
如果 GPU 编码遇到问题,可以强制使用 CPU 编码。
bash
python main.py -i ./videos -b 500K --codec hevc
使用 HEVC 压缩为 500K 码率,适合网络传输和移动端播放。
bash
python main.py -i ./videos -b 400K --codec av1
使用 AV1 编码实现最小文件体积,适合长期存储。
bash
python main.py -i ./videos -o ./output -b 1000K --copy-skipped
将所有视频(包括跳过的)都复制到输出目录,保持输出目录的完整性。
bash
python main.py -i ./videos -o ./output -b 800K -r -c
递归处理子目录,并将所有视频(包括跳过的)复制到输出目录。
python main.py -i ./videos --crf 23使用 CRF 23 进行恒定质量编码。程序会自动进行多点采样预估,默认允许文件最多增大10%以尝试压缩,实际压缩后会检测文件大小,只有更小时才采用压缩结果。
python main.py -i ./videos --crf 28 --codec hevc使用 HEVC 编码 + CRF 28,适合追求高压缩率的场景。
python main.py -i ./videos --crf 23 --min-benefit 15只有当预估压缩收益超过 15% 时才进行转码。
python main.py -i ./videos --crf 23 --max-samples 2减少采样点数以加快预估速度,适合大批量处理。
程序会自动检测原始视频的码率:
- 原始码率 ≤ 目标码率:跳过该视频,不进行任何处理
- 如果使用了
--copy-skipped参数:将原视频直接复制到输出目录 - 如果未使用该参数:仅记录日志,不复制文件
- 如果使用了
- 原始码率 > 目标码率:执行重新编码
这样可以:
- ✅ 节省处理时间
- ✅ 避免对低码率视频造成画质损失
- ✅ 保护已经足够小的视频文件
- ✅ (可选)保持输出目录包含所有原始视频
在 CRF 模式下,程序会在正式转码前进行智能采样预估:
-
智能采样策略:根据视频时长动态调整采样方案
- < 30秒:不采样,直接转码
- 30-60秒:1个采样点,10秒
- 1-3分钟:2个采样点,每段15秒
- 3-10分钟:3个采样点,每段20秒
- 10-30分钟:4个采样点,每段25秒
-
30分钟:5个采样点,每段30秒
-
真实编码测试:对每个采样片段执行真实的CRF编码
-
统计分析:计算整体压缩率和收益百分比
-
智能决策:
- 预估收益 ≥ 阈值(默认-10%):执行完整转码
- 预估收益 < 阈值:跳过转码(可选复制原文件)
- 高方差处理:当采样结果差异较大(标准差>15%)且用户设置了比默认值更保守的阈值时,使用更宽松的跳过条件(阈值-15%)
- 重要:即使预估收益为负(文件可能略微增大),也会尝试压缩,最终通过文件大小检测决定是否采用
- ✅ 准确可靠:基于真实编码而非理论估算,准确度±5%
- ✅ 避免无效二压:自动识别已高度压缩的视频(如HEVC)
- ✅ 节省时间:长视频可节省数小时无效转码
- ✅ 智能适配:自动根据视频长度调整策略
- ✅ 短视频友好:<30秒视频不采样,避免开销过大
# 平衡模式(推荐,默认)
python main.py -i ./videos --crf 23 --min-benefit -10
# 保守模式(只处理确定能减小的视频)
python main.py -i ./videos --crf 23 --min-benefit 5
# 激进模式(允许更大幅度的尝试)
python main.py -i ./videos --crf 28 --min-benefit -20
# 快速模式(大批量)
python main.py -i ./videos --crf 23 --max-samples 2详细说明请参考:CRF_SAMPLE_ESTIMATOR.md
特点:
- 🌟 兼容性最好,几乎所有设备都支持
- ⚡ 编码速度最快
- 💰 需要专利授权
- 📦 文件体积相对较大
推荐场景:
- 需要最好的兼容性
- 播放设备较老
- 需要快速转码
- 上传到老旧平台
编码器:
- GPU:
nvenc_h264,h264_qsv,h264_amf - CPU:
libx264
推荐码率:
- 1080p: 1000-2000K
- 720p: 500-1000K
- 480p: 300-500K
特点:
- 🎯 压缩效率比 H.264 高约 40-50%
- ⚡ 编码速度较快
- 💰 需要专利授权
- 📱 新设备普遍支持
推荐场景:
- 追求更好的压缩效率
- 设备较新(2018 年后)
- 存储空间有限
- 4K HDR 视频
编码器:
- GPU:
nvenc_hevc,hevc_qsv,hevc_amf - CPU:
libx265
推荐码率:
- 1080p: 600-1200K
- 720p: 400-800K
- 4K: 3000-5000K
特点:
- 🏆 压缩效率最高,比 HEVC 还高约 20-30%
- 🆓 免费开源,无专利费用
- 🐢 编码速度较慢(但 GPU 加速后很快)
- 📺 新一代设备广泛支持
推荐场景:
- 追求极致压缩效率
- 设备支持 AV1(2020 年后新款)
- 长期存储视频
- 网络带宽有限
- 希望免专利费
编码器:
- GPU:
av1_nvenc(RTX 40 系),av1_qsv(Intel Arc),av1_amf(AMD RX 7000 系) - CPU:
svt-av1(快速),libaom-av1(高质量)
推荐码率:
- 1080p: 400-800K
- 720p: 300-600K
- 4K: 2000-4000K
| 特性 | H.264 | HEVC (H.265) | AV1 |
|---|---|---|---|
| 压缩效率 | ⭐⭐⭐ 标准 | ⭐⭐⭐⭐ 高 | ⭐⭐⭐⭐⭐ 最高 |
| 编码速度 | ⭐⭐⭐⭐⭐ 最快 | ⭐⭐⭐⭐ 快 | ⭐⭐⭐ 较慢 |
| 兼容性 | ⭐⭐⭐⭐⭐ 完美 | ⭐⭐⭐⭐ 良好 | ⭐⭐⭐ 一般 |
| 专利费用 | 💰 需要 | 💰💰 需要 | ✅ 免费 |
| 文件大小 | 100% | ~50-60% | ~40-50% |
| 适用设备 | 所有设备 | 2018 年后 | 2020 年后 |
程序启动时会自动检测可用的 GPU 编码器,优先级如下:
- AV1:
av1_nvenc(RTX 40 系列及以上) - HEVC:
nvenc_hevc(GTX 10 系列及以上) - H.264:
nvenc_h264(所有支持 CUDA 的显卡)
- AV1:
av1_qsv(Arc 锐炫及以上) - HEVC:
hevc_qsv(第 6 代酷睿及以上) - H.264:
h264_qsv(第 6 代酷睿及以上)
- AV1:
av1_amf(RDNA3 RX 7000 系列) - HEVC:
hevc_amf(Polaris RX 400 系列及以上) - H.264:
h264_amf(Polaris RX 400 系列及以上)
如果未检测到 GPU,会自动回退到 CPU 编码。
使用 GPU 硬件编码可以获得:
- 速度提升:比 CPU 快 3-10 倍
- CPU 占用低:编码过程中 CPU 占用率很低
- 实时预览:适合需要快速处理的场景
⚠️ 注意:GPU 编码速度更快,但同等码率下画质略低于 CPU 编码器。
程序会根据选择的编码器自动应用最优参数:
- GPU (NVENC):
preset=p7,cq=25,temporal-aq=1 - CPU (SVT-AV1):
preset=8,crf=30,tile-columns=4 - CPU (AOM):
cpu-used=4,auto-alt-ref=1
- GPU (NVENC):
preset=p7,cq=23,tune=hq - CPU (x265):
preset=medium,crf=28,aq-mode=2
- GPU (NVENC):
preset=p7,cq=21,tune=hq - CPU (x264):
preset=medium,crf=23
- 环境准备:检查并下载 FFmpeg(首次运行)
- GPU 检测:自动检测可用的 GPU 编码器
- 扫描视频文件:根据指定目录和扩展名查找所有视频文件
- 逐文件处理:
- 检查输出文件是否存在,存在则跳过(支持断点续传)
- 检测原始视频码率和音频码率
- CRF模式:进行多点采样预估,判断是否值得转码
- 判断是否需要重新编码
- 如需编码,显示实时进度条
- 如跳过且启用
--copy-skipped,复制原文件 - 先输出为临时文件,完成后重命名
- 用户中断时自动清理临时文件
- 批量统计:显示处理进度和成功/失败统计
400K- 极低码率,适合语音视频600K- 低码率,适合移动端800K- 中等偏低码率1000K- 中等码率,平衡画质和体积(默认)1500K- 较高码率2M/2000K- 高码率,接近原画质4M/4000K- 超高清8M/8000K- 蓝光质量
FFmpeg 已就绪:D:\helloWorld\Python\videoReEncoder\ffmpeg_bin\ffmpeg.exe
正在检测 GPU 编码器...
✓ 检测到 GPU 编码器:NVIDIA NVENC AV1 (av1_nvenc)
找到 3 个视频文件
============================================================
[1/3]
正在处理:video1.mp4
使用编码器:GPU - av1_nvenc
编码格式:AV1 (最新一代)
目标视频码率:600K
原始视频码率:5,120,000 bps (5120K)
目标视频码率:600,000 bps (600K)
检测到音频码率:128000
视频总时长:120.5s
处理进度:████████████████░░░░ 85.2/120.5s [00:10<00:04, 8.5s/s]
✓ 编码完成:video1_compressed.mp4
[2/3]
正在处理:video2_low_bitrate.mp4
使用编码器:GPU - av1_nvenc
编码格式:AV1 (最新一代)
目标视频码率:600K
原始视频码率:400,000 bps (400K)
目标视频码率:600,000 bps (600K)
✓ 跳过:原始码率已低于目标码率,无需处理
[3/3]
正在处理:video3.mkv
使用编码器:GPU - av1_nvenc
编码格式:AV1 (最新一代)
目标视频码率:600K
原始视频码率:3,200,000 bps (3200K)
目标视频码率:600,000 bps (600K)
检测到音频码率:192000
视频总时长:180.3s
处理进度:████████████████░░░░ 150.5/180.3s [00:18<00:03, 9.2s/s]
✓ 编码完成:video3_compressed.mkv
============================================================
处理完成!
成功:3 个
失败:0 个
[2/3]
正在处理:video2_low_bitrate.mp4
使用编码器:GPU - av1_nvenc
编码格式:AV1 (最新一代)
目标视频码率:600K
原始视频码率:400,000 bps (400K)
目标视频码率:600,000 bps (600K)
✓ 跳过:原始码率已低于目标码率,无需处理
📋 复制原文件到输出目录...
✓ 复制完成:video2_low_bitrate.mp4
videoReEncoder/
├── main.py # 主程序入口
├── requirements.txt # Python 依赖
├── readme.md # 项目说明文档
└── ffmpeg_bin/ # 自动生成的 FFmpeg 目录(首次运行后)
├── ffmpeg.exe
└── ffprobe.exe
- 首次运行:需要网络连接下载 FFmpeg(约 30-50MB)
- 磁盘空间:转码过程会生成临时文件,请确保有足够的磁盘空间
- 原文件保护:程序不会修改原始文件,输出文件会有不同的名称或位置
- 编码时间:视频转码需要较长时间,请耐心等待
- 错误处理:如果某个文件编码失败,会继续处理下一个文件
- GPU 驱动:确保显卡驱动已更新到最新版本以获得最佳兼容性
- 时长检测:某些视频文件可能无法正确检测时长,导致进度条显示异常
- AV1 兼容性:AV1 编码需要较新的硬件支持,老旧设备可能无法播放
- 复制跳过文件:使用
--copy-skipped时,跳过的文件会保留原始文件名(不带_compressed后缀) - CRF 采样预估:CRF 模式下会先进行采样预估,长视频可能需要 1-3 分钟采样时间
- 断点续传:输出文件已存在时会自动跳过,支持中断后继续处理
- 中断清理:按 Ctrl+C 中断时会自动删除当前正在处理的临时文件
A: 首次运行会自动下载 FFmpeg,请确保网络连接正常。如果下载失败,可以手动从 ffmpeg.org 下载并将 exe 文件放到 ffmpeg_bin 目录。
A: 可以尝试以下方法:
- 更新显卡驱动到最新版本
- 使用
--cpu参数强制使用 CPU 编码 - 降低目标码率(如从 4M 降到 2M)
- 检查 GPU 是否支持硬件编码
A: 程序启动时会显示检测到的 GPU 编码器类型。处理每个视频时也会显示"使用编码器:GPU - xxx"或"使用编码器:CPU - xxx"。
A: 这可能是由于:
- 视频时长检测失败(会显示警告)
- FFmpeg 输出被缓冲(已在代码中优化)
- GPU 编码器不输出标准进度信息
可以尝试使用 --cpu 参数看是否有改善。
A:
- H.264: 需要最好兼容性,或播放设备较老
- HEVC: 追求更好的压缩效率,设备较新(2018 年后)
- AV1: 追求极致压缩效率,设备支持 AV1(2020 年后新款)⭐ 推荐
A: 当检测到原始视频码率已经低于或等于目标码率时,程序会自动跳过该视频,避免不必要的处理和画质损失。
A: 当启用此参数时,被跳过的视频(码率已低于目标值)会被直接复制到输出目录,而不是仅记录日志。这样输出目录会包含所有原始视频文件,方便统一管理。
A:
- 使用 GPU 加速(需要 RTX 40 系、Intel Arc、AMD RX 7000 系)
- 使用 SVT-AV1 编码器(比 libaom-av1 快)
- 提高 preset 值(如从 6 提高到 8)
- 考虑使用 HEVC 替代
A: 当前版本保持原始分辨率。如需调整分辨率,可以修改 encode_video 方法中的 FFmpeg 参数,添加 -vf scale=1920:1080 这样的滤镜参数。
A: 输出统一使用 AAC 编码。如果原视频没有音频流,程序也能正常处理。
A:
- NVIDIA: RTX 40 系列及以上(如 RTX 4070、4080、4090)
- Intel: Arc 锐炫 A 系列及以上(如 A750、A770)
- AMD: Radeon RX 7000 系列及以上(如 RX 7800 XT、7900 XTX)
如果不支持,程序会自动使用 CPU 编码或回退到 HEVC/H.264。
A: CRF(Constant Rate Factor)是恒定质量因子编码模式,通过设置一个质量值(0-51)来控制编码质量,而不是固定码率。数值越小质量越高,文件越大。推荐使用:
- H.264: 18-28
- HEVC: 20-30
- AV1: 25-35
A: 在 CRF 模式下,程序会在正式转码前对视频进行多点采样编码,预估压缩收益。如果预估收益低于阈值(默认10%),则跳过转码。这样可以避免对已经高度压缩的视频进行无效的二压。
A: 取决于视频长度:
- 短视频(<1分钟):不采样,无额外时间
- 中等视频(5分钟):约30-60秒采样时间
- 长视频(30分钟+):约2-3分钟采样时间
相比完整转码可能节省的数小时,这个开销非常值得。
A: 当采样结果的标准差超过15%时,说明视频内容变化较大,预估可能不准确。此时程序会根据配置采取不同策略:
情况1:使用默认或更激进的配置(min_benefit ≤ -10%)
- 高方差不会改变跳过判断逻辑
- 按照正常的阈值进行判断
情况2:使用更保守的配置(min_benefit > -10%)
- 使用更宽松的跳过条件:只有当预估收益比最小要求再低15%时才跳过
- 例如:设置 min_benefit=5%,高方差时跳过阈值为-10%(5% - 15%)
这样可以平衡处理效率和压缩机会,既不会轻易跳过可能的压缩机会,也不会对明显无效的视频浪费时间。
A: CRF 模式下,如果采样预估显示压缩收益低于设定的阈值(默认-10%),说明视频已经是高质量或已高度压缩,继续转码收益很低,因此自动跳过。默认阈值为-10%,表示允许文件最多增大10%以尝试压缩。
A: 使用 --min-benefit 参数调整最小收益阈值:
# 更保守(只处理确定能减小的视频)
python main.py -i ./videos --crf 23 --min-benefit 5
# 更激进(允许更大幅度的尝试,默认)
python main.py -i ./videos --crf 23 --min-benefit -10
# 非常激进(允许文件增大20%来尝试)
python main.py -i ./videos --crf 23 --min-benefit -20注意:即使预估文件会增大,程序在正式压缩后仍会检测实际文件大小,只有压缩后的文件更小时才会采用。
A: 程序会自动跳过该文件,不进行任何处理。这支持断点续传功能,如果中途中断,下次运行时会从上次停止的地方继续。
- ✨ 新增 CRF 多点采样预估功能,智能判断压缩收益
- ✨ 新增
--crf参数,支持恒定质量因子编码 - ✨ 新增
--min-benefit参数,自定义最小收益阈值 - ✨ 新增
--max-samples参数,调整采样点数 - ✨ 新增文件存在检测,自动跳过已存在的输出文件
- ✨ 新增中断保护,用户取消时自动清理临时文件
- 🐛 修复CRF模式下文件大小重复输出的问题
- 🐛 删除原有的理论CRF估算功能,统一使用采样预估
- ✨ 新增
--copy-skipped参数,支持将跳过的视频复制到输出目录 - 🐛 优化文件复制逻辑,保留文件元数据
- ✨ 新增 AV1 编码格式支持
- ✨ 支持 H.264/HEVC/AV1 三种编码格式
- ✨ 自动检测并选择最优编码器
- ✨ 针对不同编码器优化参数
- 🐛 修复编码参数兼容性问题
- ✨ 新增便携模式,自动下载 FFmpeg
- ✨ 新增 GPU 硬件加速支持(NVIDIA/Intel/AMD)
- ✨ 新增智能码率检测,自动跳过低码率视频
- ✨ 新增实时进度条显示
- 🐛 修复编码参数兼容性问题
- 🐛 修复字符编码导致的错误
- 初始版本发布
本项目采用 GNU General Public License v3.0 (GPL-3.0) 许可证进行许可。
完整的许可证文本请参阅项目中的 LICENSE 文件。
更多信息请访问:https://www.gnu.org/licenses/gpl-3.0.html
欢迎提交 Issue 和 Pull Request!通过向本项目提交代码,你同意你的贡献也遵循 GPL-3.0 许可证。