一段32秒的竖屏短片,旁白从头到尾没有一个字是真人录的。整套流程跑在本地机器上,不连付费接口,也不碰GPU——靠的是一个开源TTS(文本转语音)工具Piper,加上ffmpeg收尾。

打开网易新闻 查看精彩图片

起因很朴素:短片的葡萄牙语旁白需要有人念,但一开始不想被付费API绑住。Piper的定位正好对上——开源、许可证GPL-3.0、离线运行、吃CPU,而且自带巴西葡萄牙语(pt-BR)音色。整套操作在Debian上完成,Python 3.12,piper-tts版本1.8.0。

第一步:装进虚拟环境

先建一个venv,避免把系统Python搅乱,然后一条pip命令装完。不需要显卡,包里已经带了处理音素要用的espeak-ng。

  • 建目录、进目录
  • python3 -m venv .venv 建虚拟环境
  • 激活后 pip install piper-tts

第二步:下载巴西葡语音色

用的是faber,medium质量档,模型卡标注数据集为CC0。下载命令会往当前目录放两个文件:pt_BR-faber-medium.onnx,约63MB,以及配套的.onnx.json配置。两个文件必须待在一起,缺一个都跑不起来。

第三步:生成第一段音频

把台词写进一个txt,用piper指定模型、输入文件和输出wav。实测在CPU上,生成约4秒音频花了不到2秒。用ffprobe核对结果:采样率22050、时长4.179592秒。

几个值得记住的参数:--length-scale 1.1让语速变慢,0.9则加快;--sentence-silence 0.3在句子之间插入停顿;--volume 1.2把音量调大。完整参数列表用--help查看。

第四步:批量生成,一句一文件

做视频时更习惯一个场景对应一个音频文件,后面同步字幕和画面会轻松很多。做法是脚本里加载一次音色模型,再按行遍历台词逐条合成,一行台词等于一个场景。这里还藏着一个坑:英文品牌名会被按它自己的规则读出来。应对办法是准备两份文本,一份给字幕用原文,一份给语音用——按想听到的发音重新拼写。

第五步:拼接并统一响度

短视频平台通常工作在-14 LUFS附近,ffmpeg的loudnorm滤镜可以对齐。先把所有分段wav写进一个列表文件,再用concat拼接,同时挂上loudnorm=I=-14:TP=-1.5:LRA=11,输出44100采样率的成品。想确认实际数值,用ebur128滤镜跑一遍看Integrated读数。

需要提醒的是,短片段用单遍loudnorm会略微低于目标。对短片来说够用;要精确压到目标值,就做两遍loudnorm。

第六步:合成竖屏视频

最小方案是一张1080x1920的图片加最终音频。ffmpeg用loop读图,scale到竖屏尺寸、转yuv420p,帧率30,视频编码libx264并加stillimage调优,音频走aac 160k,最后用shortest让时长对齐。ffprobe验证输出:h264、1080x1920、30/1,音频aac。

更完整的流水线会在此基础上加东西:每个场景一张图配zoompan做缓慢推近,字幕用.ass文件通过ass滤镜烧进画面。骨架还是上面这套。

边界在哪

这套方案的短板得说清楚。音色用来做教程、用来试格式没问题,但语调比付费服务更平,偶尔还会在某个词上打滑。如果项目要求高度自然的嗓音,或者需要克隆自己的声音,那就该去看ElevenLabs或Murf这类服务。Fish Audio目前没有在TTS里列出葡萄牙语。

整条链路的价值在于:从零到一条竖屏mp4,全部在本地完成,成本压到零,代价是接受机器嗓的那点平直。