rewrite for robustness.

This commit is contained in:
2026-04-13 21:05:23 +08:00
parent 6a5c70d6fe
commit fcfd425981
4 changed files with 228 additions and 138 deletions

View File

@@ -5,44 +5,42 @@
唯一不可或缺的只有`ffmpeg`。无论 Windows 还是 Linux获取这个软件包并不难。
可选第三方 Python 库:`tqdm``colorlog`,让终端输出更“摩登”一些
可选第三方 Python 库:`tqdm``colorlog`。没有也没关系,接口是兼容的
<details>
## 应用
有两种命令行调用。当模块导入挑着用也没问题,只是没必要。
<summary>fallback</summary>
- `cmps_hevc_crf18 [-d SRCDIR] [-o OUTDIR] [-f EXT1] [-f EXT2] [-r] [-s]`
- `cmps_hevc_crf18 [-r] [-s] [-o OUTDIR] files`
我的模块旨在作为脚本\*单文件运行\*,随意加第三方依赖自然意味着没办法开箱即用。因此,哪怕是部署上我的 Ubuntu Server我也得考虑 ImportError 时的回滚方案。
剩下的直接翻译 argparse 帮助文本得了:
```
编码视频文件为 HEVC CRF 18MP4格式。
- `colorlog`:其仓库文档就介绍了跟标准库组合使用的案例。仔细读就不难发现:传入不同`Formatter`即可。
- `tqdm`:那自然是手撕一个`RawProgressBar`了。毕竟使用场景简单,我撕出来的进度条只实现了用到的方法和`__init__`参数。
位置参数:
files 单独的视频文件(与 -d 互斥,二选一)
</details>
选项:
-h, --help 鹰文帮助
-d, --dir SRCDIR 源文件夹(会在里面搜索指定后缀的文件,与 files 互斥)
-o, --outdir OUTDIR 输出文件夹(默认原地,跟 -d 合用会保留相对路径)
-f, --ext EXTENSIONS 指定的后缀名(.mp4 和 mp4 均可,可重复指定多个后缀,不区分大小写)
-r, --rm-original 跑完是否把原文件删了
-s, --silent 静默(不显示进度条)
```
## 背景
最初看到类似的实践其实是在某个涩涩论坛上。原帖将近 180GB 的原始资源压制到 30+GB 且几乎不怎么影响画质,巨大的体积差引起了我的兴趣。
后来在 QQ 群里有人给出了这么个命令行:
实际就是命令行:
```sh
ffmpeg -i input.mp4 -c:v libx265 -crf 18 -preset medium -c:a copy -tag:v hvc1 output.mp4
```
这一行命令参数就是窝脚本的核心逻辑了。和大多数在 Python 封装 ffmpeg 调用的第三方库一样,我也只是包装一下
写那么多 Python 封装只是为了路径处理和好看一点的终端输出
## 后记
前身也是个 Bash 脚本。奈何在 Bash 里折腾路径实在是有些疲累。有一次出现了我没考虑到的边界情况:
```bash
abs_src="/home/agxcoy/Downloads/blabla"
out_dir="~/Videos/blabla"
relpath="subdir/sub.mp4"
# => mkdir -p "/home/agxcoy/Videos//home/agxcoy/Downloads/blabla/subdir/"
而在 Windows 里文件所有权并不复杂(当前用户通常都可以读写),我更倾向于用 PowerShell
```powershell
get-childitem path -File -Recurse -Filter *.mp4 | foreach {
cmps_hevc $_.FullName # 依旧 ffmpeg也就变换一下 input.mp4 output.mp4
rename-item $_.FullName "$($_.Name).bak"
}
```
气笑了。
然后最初是打算`os.walk`,但问了下 Google AI、VSCode Copilot发现`pathlib`还真挺好用,就整个“翻译”完替换掉 Bash 版了。
## 已知问题
事实上边界情况还没测试完全,现在也不过能正常走完我的基本流程罢了。
除此之外,进度条本身也有点问题。我应该先在外面四舍五入`current_time` `total_time`再丢进进度条里显示的。因为在`tqdm`那看到了`327.099...9/660.377007`这么长的文字。
再者就是性能问题了。我处理的视频文件基本以 GB 计。同时跑太多 ffmpeg 进程,内存不够分(我在 Server 上`tmux`挂后台,似乎日志写多了还出现了掉盘)。逐个逐个跑吧,性能使用率不高。我看有些 ffmpeg 封装库利用了线程池和 asyncio值得参考。
就算后续还要筛选(好比有的视频压制完比原文件还大),也比 Python 方便得多。