氛围编程与需求膨胀:小记一次音频处理的折腾

安迪给的,比尔就会拿走。神女应无恙,当惊世界殊。

昨晚利用 AI 辅助,没用 IDE,但也算是 vibe coding 地做了一个小工具:

  • 对着一个.mp3文件右键,选择「快速操作 - 音频双语翻译并选择视频」
  • 即可自动对音频转写出.srt字幕,并翻译成中文,然后合并成双语的.srt字幕
  • 同时会将 mp3 转为 mp4,用于播放视频时加载字幕

最初的折腾

最初我手里有一份 .mp3 的音频文件,我想快速看一下转写的英文,再丢进翻译软件里看一下中文。我大概知道现在的比较通用的转写(STT),基本都是各种 GUI 套开源 whisper 的壳。之前在 macOS 商店里安装过一个「Whisper Transcription」的软件,把音频文件丢进去,顺利得到了.srt 以及翻译成中文后的 .srt

此时我手里已经有两份.srt了,想使用时发现了第一个问题:macOS 上的各类播放器,如 IINA、VLC 等,不支持播放音频时同时加载字幕文件,.lrc 都不行,更遑论.srt了。而且 .srt本身就是针对视频的字幕格式。

和 ChatGPT 聊了一下(此处感谢友人送的 Pro ,我狂用),给了诸多方案,选了一个「音频转视频」的方案,即用 ffmpeg 把音频直接转成视频。因为之前装过 ffmpeg 也用过,于是很顺手的又问了一嘴命令,直接在终端操作了。能跑,但是很慢,再问一嘴,原来是帧率的问题,从30帧改成1帧后,这个指令基本就算跑通了:

ffmpeg -i audio`.mp3` \
-f lavfi -i color=c=black:s=640x360:r=1 \
-shortest \
-c:v libx264 -preset ultrafast -crf 35 -pix_fmt yuv420p \
-c:a copy \
-movflags +faststart \
out`.mp4`

第一次膨胀:我要双语字幕

现在有了视频就可以加载.srt字幕了,此时我觉得加载双语字幕肯定是更合适的,因为直接转写+机翻后的误差还是存在的,于是打开了 IINA(macOS 上主流的开源播放器),然后意外地发现 IINA 的副字幕居然只能在视频最上方,不能调整。

这个过程里 GPT 基本是顺从性的骗人,我问怎么把 IINA 的副字幕挪到下方,煞有介事给我出了几个方案,我说你你说的这个参数没用,他就说,是的,IINA 是原生不支持的。最后确认了下 IINA 是基于 mpv 这个库来开发的,mpv 不支持,IINA 也没有额外支持。

这个时候我说:给我写个 pyhton 脚本,把这俩同名的.srt合并了吧,英文第一行中文第二行。这种公共知识型的代码还是很容易的,AI 很迅速地给了我一版,并且完全可用。

第二次膨胀:我要一键操作

但是这个时候依旧是要从终端开始 cd,手敲命令的。于是我问:我希望你帮我写一个在 mac 上可以直接运行的小工具,支持上面两个需求。AI 返了一个二合一的脚本,依旧还是麻烦。我继续追问:我该如何让这个工具更易用?

AI 给出了几个方案:

  1. 把脚本放到 bin 或者 PATH 里
  2. 用 Automator 或 Shortcuts
  3. 写 GUI

想了想,似乎 Automator(快速操作,苹果官方的一个图形化工作流软件),更可靠,成本更低。于是我说:用 Automator 的方案吧。GPT 给了一版,照例跑测后又修了一版。到这里,最多返回改一次代码,整体还是很顺利的。

分叉路:通知

这时注意到,Automator 执行完后没有返回通知,于是又让 GPT 加了一个通知。在这个地方卡了很多轮,最后发现似乎是 Automator 走不了 macOS 的系统通知,所以用 AppleScript 的弹窗来曲线救国了。

但因为是批量处理,我开始希望通知可以更完整地列表打印处理的文件名,而不是返回一个简单的计数。这里和 AI 聊了好几轮,代码总有 bug,因为报错的信息不完善(操作“运行 AppleScript”遇到了错误:未能完成操作。(com.apple.Automator 错误-212。))。最后我说:算了,不折腾了,改回原来那版。

第三次膨胀:我还要更一步到位

这个时候忽然想,反正反正 whisper 是开源模型,然后翻译我再调一下 API,为何不一键完成全流程(CLI Whisper + 翻译 + 合并字幕 + 转mp4)呢?

说干就干,和 GPT 讨论完之后他让我找模型(ggml-*.bin)放在本地,然后用 whisper-cpp。但是 whisper 模型我实在 openai 官网下的 .pt 文件,也懒得折腾了,问了两下之后很顺畅的放弃 whisper-cpp,转了 Python Whisper。

pip3 install -U openai-whisper

哈哈,又报错,跟我说还要创建一个虚拟环境:

python3 -m venv ~/venvs/whisper

继续追问最终的 Shell 脚本,又返了一轮报错,之后可用。针对翻译的 API-key 填在哪里又折腾了一下,最后依旧是懒得折腾,填在 shell 脚本里就完事。

然后依旧是进度问题,因为接入了转写和翻译,流程更长了,看不到进度很焦虑,又让优化了一版日志,直接在桌面输出一个.log 文件。macOS 这方面还挺好的,直接用终端打开.log,还能看到实时的更新。

总结与回顾:

到此为止这个需求逐渐膨胀的氛围编程就全部结束了。明显还可以优化的点就是 shell 脚本里的翻译模型是写死的,用的 gpt-4o-mini,后面看看有没有更好的转写+翻译方案。

回看整个两三个小时的折腾的历程,其实就是一件小事:

  1. 我的原始需求:存在一个音频文件,希望可以获得字幕并配合音频观看字幕
  2. 主要遇到的问题:macOS 上的播放器(如 IINA)不支持播放音频文件同时加载字幕

膨胀出来的新需求:

  1. 双语字幕的显示,IINA 不支持修改副字幕位置
  2. 傻瓜化的一键操作,返回通知或日志

折腾出出工具 1:automator 脚本,可以右键文件使用

  1. 使用Shell 脚本调用 python 脚本,AppleScript 返回弹窗
  2. 将文件夹内的 mp3 转 mp4,并且合并同名的中英文字幕

折腾出工具 2:同样automator 脚本,可以右键文件使用

  1. 完全使用 Shell 脚本
  2. 基于 whisper 模型本地转写 srt 字幕
  3. 调用 OpenAI 的 API 翻译并合并成双语字幕
  4. 将 mp3 转 mp4
  5. 以及整个进程的可视化日志

我们可以发现,在某些公共知识场域内,AI 效率非常之高,哪怕只是简单的对话模型,没有上 Agent,也可以当成产品+技术,来同时讨论需求和实现。

唯二的问题,一个是幻觉+谄媚导致的错误方案,其二是局部确实会卡住,比如这次的通知问题。这时需要自身对相关内容有一定的了解和判断,当遇到卡点时,能不能转圜一下,或者干脆该放弃就放弃。只要不陷入死磕状态,整个流程的效率确实是非常之高的。

这次折腾的过程,回过头来看比较有趣的是,这是一个需求逐渐膨胀的过程。就像安迪-比尔定律,「安迪给的,比尔就会拿走」,新硬件所提高的任何计算能力,新软件总是将其占满。一旦工具(AI)展露出解决能力的能力,就会提出新的问题,直到 AI 不再能解决(比如通知)。

回想上一次使用 automator 时,差不多还是七八年前,当时我还只是自己搞了个批量重命名去括号的工具,这次居然直接搞定了一个这么复杂的流程。

神女应无恙,当惊世界殊。