Communitygithub.com

hadi-a-azeez/viral-voice

为无脸短视频添加配音、逐字字幕和音效,并生成最终视频。支持免费AI语音(马拉雅拉姆语、英语、印地语、泰米尔语等)、ElevenLabs或用户自己的录音。适用于需要为动画短片添加配音、字幕或音效的场景,是viral pack系列的第四步。

viral-voice 是什么?

viral-voice是viral pack工具链中的第四步,专注于为无脸短视频(faceless reel)添加专业级的配音、逐字字幕和音效,并最终渲染导出成品视频。它通过Python脚本与项目文件交互,提供三种语音选项:免费的内置AI语音(基于edge-tts,支持多种印度语言)、ElevenLabs付费API、以及用户自录音频(支持整段或按节拍分批录制)。字幕时序会根据语音引擎自动调整:免费和ElevenLabs版本可实现精确的逐词点亮,自录音频则基于停顿估算,按节拍录制可大幅提高精度。此外,该工具还能根据语音时长自动调整动画运动(通过viral-animate),并内置了合成的音效库(如whoosh、pop、thump等),无需担心版权问题。用户需注意,AI语音质量虽清晰但略显平淡,edge-tts非官方API可能变化,商用前应检查条款。最终通过finish.py混音并标准化响度至-14 LUFS,输出final.mp4。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/hadi-a-azeez/viral-agent/tree/main/skills/viral-voice

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

viral-voice 是做什么的?

运行一次初始化:bash setup.sh。本指南中的脚本位于此文件旁边,请使用它们的完整路径。

1. 选择语音

询问用户想要哪种,并直接说明权衡:

选项成本质量字幕时序
免费语音(默认)免费清晰,略显平淡精确,每个词在说出时点亮
ElevenLabs他们的付费套餐或免费额度最自然当模型提供时间戳时精确
用户自己的声音免费最个性化每行内估算。按节拍录制则更精确

用户自己的声音通常效果最好,因为人们能听出其中的诚意。无脸短视频不必无声。

# 免费语音。选择Midhun用于马拉雅拉姆语。使用 --voice ml-IN-SobhanaNeural 获取另一种马拉雅拉姆语语音。
python3 voice.py <project>

# ElevenLabs。需要 ELEVENLABS_API_KEY 和语音ID。马拉雅拉姆语需要支持它的模型,例如 eleven_v3。
python3 voice.py <project> --engine elevenlabs --voice <voice id> --model eleven_v3

# 用户自己的录音,整个脚本一次录制完成
python3 voice.py <project> --engine file --audio take.m4a

# 用户自己的录音,按节拍分文件(voice/b1.m4a, voice/b2.m4a)。这种方式时序更精确。
python3 voice.py <project> --engine file --audio voice/

来自其他工具的音频也可以通过 --engine file 使用,因此如果连接了语音生成工具,为每个节拍生成一个文件并传递文件夹。

对于录音,每行的字幕通过单词长度和停顿来计时。因此在一次长录音中,字幕可能偏差约一秒。在我们对一个真实的48秒马拉雅拉姆语短视频的测试中,大多数字幕误差在半秒内。如果看起来不对,请按节拍录制。

免费语音通过开源工具 edge-tts 运行在微软Edge的朗读服务上。这不是官方API,因此可能会改变或停止工作,任何将其用于客户或商业工作的人都应首先检查条款。如果用户正在为商业制作视频,请说明这一点。

2. 需要有人听

这些工具无法听到音频,timing.json 只显示脚本中的单词,从不显示实际说的内容。因此这里无法确认发音。要求用户听取 voice.wav,或者如果连接了转录工具,则转录并与脚本比较。如果两者都没有,直接说明语音未经审核。

当语音错误地读出一个词时,在 script.json 中为该节拍添加 "tts",使用它能正确拼写的拼写,然后重新运行。字幕继续使用 say。尽可能保持 tts 中的单词数量与 say 相同。如果不同,voice.py 会打印一条注释,并且该节拍的字幕时间变为估算值。

如果一行听起来太急促,更改 --rate(默认 +8%)。--gap 设置节拍之间的停顿。

来自 lint_script.py 和 timing.py 的长度估算只是粗略的,可能短10-15%。实际长度是 voice.py 打印的。要达到目标,请更改 --rate 或删减单词,然后重新运行。

3. 再次查看画面

真实的语音已经移动了所有内容,因此在最终渲染之前查看:

node <viral-animate folder>/render.mjs <project> --stills beats

打开 stills/beats.jpg。绑定到 k、d 或 kit.at 的运动已跟随语音。任何具有固定秒数的运动则没有,因此需要在 scenes.js 中修复它们。

4. 音效

sfx.py 会自动运行:开始时有一个低沉的重击声,每个节拍变化时有一个轻柔的呼啸声。对于安静、情感化的片段,通过 script.json 中的 "sfx_auto": false 关闭它们。要添加更多音效,请列出它们,定位到某个单词以保持同步:

"sfx": [{ "beat": "b2", "word": "charger", "kind": "pop", "db": -14 }]

使用 "at": 1.1 替代 word 表示节拍内的秒数。如果节拍中没有该单词,则停止并给出清晰的消息。音效种类:

种类听起来像适用于
whoosh swell上升的空气变化、飞入物
swipe快速刷过的空气快速移动
pop小的圆润爆裂声出现的事物
tick细小的干枯滴答声计数器、小瞬间
click干脆的开关点击声灯开关、按钮
knock指节敲木声门、桌子
thump低沉的重击声开场、大揭示
stamp带有重量的硬拍判决、强调观点

它们都是合成的,因此没有授权风险。本工具包不添加音乐:它保持语音清晰并避免版权问题。如果用户想要音乐,可以在Instagram编辑器中添加。

5. 完成

python3 finish.py <project>

这会根据实际语音时序渲染全质量画面,混入音效,将响度设置为约-14 LUFS并写入 final.mp4。添加 --no-render 仅重新混音。

试用版本: 要测试其他钩子,复制项目文件夹,将另一个钩子的 say 放入 b1,将其 label 放入顶层 label,然后在副本上运行 voice.py 和 finish.py。绑定到 k、d 或 kit.at 的运动会跟随。检查 kit.at 中的单词是否仍然存在于新钩子中。

然后前往 /viral-check。在此之前不要认为短视频已完成。

相关技能