Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Video ReEncoder - 视频批量压缩工具

一个基于 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(可选,用于硬件加速)

快速开始

1. 安装依赖

bash
pip install -r requirements.txt

依赖说明:

  • ffmpeg-python>=0.2.0:Python 操作的 FFmpeg 绑定库
  • urllib3>=1.26.0:用于下载 FFmpeg
  • tqdm>=4.65.0:用于显示进度条

2. 运行脚本

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采样预估的最大采样点数

使用示例

示例 1:基本使用(H.264,默认码率 1000K)

bash
python main.py -i ./videos

输出文件将保存在源文件同目录,文件名添加 _compressed 后缀。

示例 2:自定义码率和输出目录(HEVC 编码)

bash
python main.py -i ./videos -o ./output -b 800K --codec hevc

使用 HEVC 编码将视频压缩为 800K 码率,并保存到 output 目录。

示例 3:递归处理子目录(AV1 编码)

bash
python main.py -i ./videos -o ./output -b 600K --codec av1 -r

使用 AV1 编码递归处理 videos 目录下所有子目录中的视频文件。

示例 4:强制使用 CPU 编码

bash
python main.py -i ./videos -b 1000K --cpu

如果 GPU 编码遇到问题,可以强制使用 CPU 编码。

示例 5:低码率压缩(适合移动端)

bash
python main.py -i ./videos -b 500K --codec hevc

使用 HEVC 压缩为 500K 码率,适合网络传输和移动端播放。

示例 6:极致压缩(AV1 编码)

bash
python main.py -i ./videos -b 400K --codec av1

使用 AV1 编码实现最小文件体积,适合长期存储。

示例 7:复制跳过的视频到输出目录

bash
python main.py -i ./videos -o ./output -b 1000K --copy-skipped

将所有视频(包括跳过的)都复制到输出目录,保持输出目录的完整性。

示例 8:递归处理并复制所有文件

bash
python main.py -i ./videos -o ./output -b 800K -r -c

递归处理子目录,并将所有视频(包括跳过的)复制到输出目录。

示例 9:使用 CRF 模式(推荐)

python main.py -i ./videos --crf 23

使用 CRF 23 进行恒定质量编码。程序会自动进行多点采样预估,默认允许文件最多增大10%以尝试压缩,实际压缩后会检测文件大小,只有更小时才采用压缩结果。

示例 10:CRF 模式 + HEVC 编码

python main.py -i ./videos --crf 28 --codec hevc

使用 HEVC 编码 + CRF 28,适合追求高压缩率的场景。

示例 11:CRF 模式自定义收益阈值

python main.py -i ./videos --crf 23 --min-benefit 15

只有当预估压缩收益超过 15% 时才进行转码。

示例 12:CRF 模式快速模式

python main.py -i ./videos --crf 23 --max-samples 2

减少采样点数以加快预估速度,适合大批量处理。

技术细节

智能码率检测

程序会自动检测原始视频的码率:

  • 原始码率 ≤ 目标码率:跳过该视频,不进行任何处理
    • 如果使用了 --copy-skipped 参数:将原视频直接复制到输出目录
    • 如果未使用该参数:仅记录日志,不复制文件
  • 原始码率 > 目标码率:执行重新编码

这样可以:

  • ✅ 节省处理时间
  • ✅ 避免对低码率视频造成画质损失
  • ✅ 保护已经足够小的视频文件
  • ✅ (可选)保持输出目录包含所有原始视频

CRF 多点采样预估(新增)

在 CRF 模式下,程序会在正式转码前进行智能采样预估:

工作原理

  1. 智能采样策略:根据视频时长动态调整采样方案

    • < 30秒:不采样,直接转码
    • 30-60秒:1个采样点,10秒
    • 1-3分钟:2个采样点,每段15秒
    • 3-10分钟:3个采样点,每段20秒
    • 10-30分钟:4个采样点,每段25秒
    • 30分钟:5个采样点,每段30秒

  2. 真实编码测试:对每个采样片段执行真实的CRF编码

  3. 统计分析:计算整体压缩率和收益百分比

  4. 智能决策

    • 预估收益 ≥ 阈值(默认-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

支持的编码格式

1️⃣ H.264 (AVC) - 兼容性最佳

特点:

  • 🌟 兼容性最好,几乎所有设备都支持
  • ⚡ 编码速度最快
  • 💰 需要专利授权
  • 📦 文件体积相对较大

推荐场景:

  • 需要最好的兼容性
  • 播放设备较老
  • 需要快速转码
  • 上传到老旧平台

编码器:

  • GPU: nvenc_h264, h264_qsv, h264_amf
  • CPU: libx264

推荐码率:

  • 1080p: 1000-2000K
  • 720p: 500-1000K
  • 480p: 300-500K

2️⃣ HEVC (H.265) - 高效平衡

特点:

  • 🎯 压缩效率比 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

3️⃣ AV1 - 最新一代 ⭐ 强烈推荐

特点:

  • 🏆 压缩效率最高,比 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 硬件加速

程序启动时会自动检测可用的 GPU 编码器,优先级如下:

NVIDIA GPU

  1. AV1: av1_nvenc (RTX 40 系列及以上)
  2. HEVC: nvenc_hevc (GTX 10 系列及以上)
  3. H.264: nvenc_h264 (所有支持 CUDA 的显卡)

Intel GPU

  1. AV1: av1_qsv (Arc 锐炫及以上)
  2. HEVC: hevc_qsv (第 6 代酷睿及以上)
  3. H.264: h264_qsv (第 6 代酷睿及以上)

AMD GPU

  1. AV1: av1_amf (RDNA3 RX 7000 系列)
  2. HEVC: hevc_amf (Polaris RX 400 系列及以上)
  3. H.264: h264_amf (Polaris RX 400 系列及以上)

如果未检测到 GPU,会自动回退到 CPU 编码。

性能对比

使用 GPU 硬件编码可以获得:

  • 速度提升:比 CPU 快 3-10 倍
  • CPU 占用低:编码过程中 CPU 占用率很低
  • 实时预览:适合需要快速处理的场景

⚠️ 注意:GPU 编码速度更快,但同等码率下画质略低于 CPU 编码器。

编码参数优化

程序会根据选择的编码器自动应用最优参数:

AV1 参数

  • 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

HEVC 参数

  • GPU (NVENC): preset=p7, cq=23, tune=hq
  • CPU (x265): preset=medium, crf=28, aq-mode=2

H.264 参数

  • GPU (NVENC): preset=p7, cq=21, tune=hq
  • CPU (x264): preset=medium, crf=23

工作流程

  1. 环境准备:检查并下载 FFmpeg(首次运行)
  2. GPU 检测:自动检测可用的 GPU 编码器
  3. 扫描视频文件:根据指定目录和扩展名查找所有视频文件
  4. 逐文件处理
    • 检查输出文件是否存在,存在则跳过(支持断点续传)
    • 检测原始视频码率和音频码率
    • CRF模式:进行多点采样预估,判断是否值得转码
    • 判断是否需要重新编码
    • 如需编码,显示实时进度条
    • 如跳过且启用 --copy-skipped,复制原文件
    • 先输出为临时文件,完成后重命名
    • 用户中断时自动清理临时文件
  5. 批量统计:显示处理进度和成功/失败统计

支持的码率格式

  • 400K - 极低码率,适合语音视频
  • 600K - 低码率,适合移动端
  • 800K - 中等偏低码率
  • 1000K - 中等码率,平衡画质和体积(默认)
  • 1500K - 较高码率
  • 2M / 2000K - 高码率,接近原画质
  • 4M / 4000K - 超高清
  • 8M / 8000K - 蓝光质量

输出示例

正常处理流程(AV1 编码)


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

注意事项

  1. 首次运行:需要网络连接下载 FFmpeg(约 30-50MB)
  2. 磁盘空间:转码过程会生成临时文件,请确保有足够的磁盘空间
  3. 原文件保护:程序不会修改原始文件,输出文件会有不同的名称或位置
  4. 编码时间:视频转码需要较长时间,请耐心等待
  5. 错误处理:如果某个文件编码失败,会继续处理下一个文件
  6. GPU 驱动:确保显卡驱动已更新到最新版本以获得最佳兼容性
  7. 时长检测:某些视频文件可能无法正确检测时长,导致进度条显示异常
  8. AV1 兼容性:AV1 编码需要较新的硬件支持,老旧设备可能无法播放
  9. 复制跳过文件:使用 --copy-skipped 时,跳过的文件会保留原始文件名(不带 _compressed 后缀)
  10. CRF 采样预估:CRF 模式下会先进行采样预估,长视频可能需要 1-3 分钟采样时间
  11. 断点续传:输出文件已存在时会自动跳过,支持中断后继续处理
  12. 中断清理:按 Ctrl+C 中断时会自动删除当前正在处理的临时文件

常见问题

Q: 为什么第一次运行时报错?

A: 首次运行会自动下载 FFmpeg,请确保网络连接正常。如果下载失败,可以手动从 ffmpeg.org 下载并将 exe 文件放到 ffmpeg_bin 目录。

Q: GPU 编码失败怎么办?

A: 可以尝试以下方法:

  1. 更新显卡驱动到最新版本
  2. 使用 --cpu 参数强制使用 CPU 编码
  3. 降低目标码率(如从 4M 降到 2M)
  4. 检查 GPU 是否支持硬件编码

Q: 如何查看使用了哪种编码器?

A: 程序启动时会显示检测到的 GPU 编码器类型。处理每个视频时也会显示"使用编码器:GPU - xxx"或"使用编码器:CPU - xxx"。

Q: 进度条一直为 0 怎么办?

A: 这可能是由于:

  1. 视频时长检测失败(会显示警告)
  2. FFmpeg 输出被缓冲(已在代码中优化)
  3. GPU 编码器不输出标准进度信息

可以尝试使用 --cpu 参数看是否有改善。

Q: 三种编码格式应该选哪个?

A:

  • H.264: 需要最好兼容性,或播放设备较老
  • HEVC: 追求更好的压缩效率,设备较新(2018 年后)
  • AV1: 追求极致压缩效率,设备支持 AV1(2020 年后新款)⭐ 推荐

Q: 为什么有些视频被跳过了?

A: 当检测到原始视频码率已经低于或等于目标码率时,程序会自动跳过该视频,避免不必要的处理和画质损失。

Q: --copy-skipped 参数有什么用?

A: 当启用此参数时,被跳过的视频(码率已低于目标值)会被直接复制到输出目录,而不是仅记录日志。这样输出目录会包含所有原始视频文件,方便统一管理。

Q: AV1 编码很慢怎么办?

A:

  1. 使用 GPU 加速(需要 RTX 40 系、Intel Arc、AMD RX 7000 系)
  2. 使用 SVT-AV1 编码器(比 libaom-av1 快)
  3. 提高 preset 值(如从 6 提高到 8)
  4. 考虑使用 HEVC 替代

Q: 如何调整视频分辨率?

A: 当前版本保持原始分辨率。如需调整分辨率,可以修改 encode_video 方法中的 FFmpeg 参数,添加 -vf scale=1920:1080 这样的滤镜参数。

Q: 支持哪些音频编码格式?

A: 输出统一使用 AAC 编码。如果原视频没有音频流,程序也能正常处理。

Q: 我的显卡支持 AV1 编码吗?

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。

Q: 什么是 CRF 模式?

A: CRF(Constant Rate Factor)是恒定质量因子编码模式,通过设置一个质量值(0-51)来控制编码质量,而不是固定码率。数值越小质量越高,文件越大。推荐使用:

  • H.264: 18-28
  • HEVC: 20-30
  • AV1: 25-35

Q: CRF 采样预估是什么?

A: 在 CRF 模式下,程序会在正式转码前对视频进行多点采样编码,预估压缩收益。如果预估收益低于阈值(默认10%),则跳过转码。这样可以避免对已经高度压缩的视频进行无效的二压。

Q: 采样预估会增加多少时间?

A: 取决于视频长度:

  • 短视频(<1分钟):不采样,无额外时间
  • 中等视频(5分钟):约30-60秒采样时间
  • 长视频(30分钟+):约2-3分钟采样时间

相比完整转码可能节省的数小时,这个开销非常值得。

Q: 如果采样结果差异很大怎么办?

A: 当采样结果的标准差超过15%时,说明视频内容变化较大,预估可能不准确。此时程序会根据配置采取不同策略:

情况1:使用默认或更激进的配置(min_benefit ≤ -10%)

  • 高方差不会改变跳过判断逻辑
  • 按照正常的阈值进行判断

情况2:使用更保守的配置(min_benefit > -10%)

  • 使用更宽松的跳过条件:只有当预估收益比最小要求再低15%时才跳过
  • 例如:设置 min_benefit=5%,高方差时跳过阈值为-10%(5% - 15%)

这样可以平衡处理效率和压缩机会,既不会轻易跳过可能的压缩机会,也不会对明显无效的视频浪费时间。

Q: 为什么有些视频被跳过了(CRF模式)?

A: CRF 模式下,如果采样预估显示压缩收益低于设定的阈值(默认-10%),说明视频已经是高质量或已高度压缩,继续转码收益很低,因此自动跳过。默认阈值为-10%,表示允许文件最多增大10%以尝试压缩。

Q: 如何调整采样预估的灵敏度?

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

注意:即使预估文件会增大,程序在正式压缩后仍会检测实际文件大小,只有压缩后的文件更小时才会采用。

Q: 输出文件已存在时会怎样?

A: 程序会自动跳过该文件,不进行任何处理。这支持断点续传功能,如果中途中断,下次运行时会从上次停止的地方继续。

更新日志

v1.4(当前版本)

  • ✨ 新增 CRF 多点采样预估功能,智能判断压缩收益
  • ✨ 新增 --crf 参数,支持恒定质量因子编码
  • ✨ 新增 --min-benefit 参数,自定义最小收益阈值
  • ✨ 新增 --max-samples 参数,调整采样点数
  • ✨ 新增文件存在检测,自动跳过已存在的输出文件
  • ✨ 新增中断保护,用户取消时自动清理临时文件
  • 🐛 修复CRF模式下文件大小重复输出的问题
  • 🐛 删除原有的理论CRF估算功能,统一使用采样预估

v1.3

  • ✨ 新增 --copy-skipped 参数,支持将跳过的视频复制到输出目录
  • 🐛 优化文件复制逻辑,保留文件元数据

v1.2

  • ✨ 新增 AV1 编码格式支持
  • ✨ 支持 H.264/HEVC/AV1 三种编码格式
  • ✨ 自动检测并选择最优编码器
  • ✨ 针对不同编码器优化参数
  • 🐛 修复编码参数兼容性问题

v1.1

  • ✨ 新增便携模式,自动下载 FFmpeg
  • ✨ 新增 GPU 硬件加速支持(NVIDIA/Intel/AMD)
  • ✨ 新增智能码率检测,自动跳过低码率视频
  • ✨ 新增实时进度条显示
  • 🐛 修复编码参数兼容性问题
  • 🐛 修复字符编码导致的错误

v1.0

  • 初始版本发布

许可证

本项目采用 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 许可证。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages