Install
$ agentstack add skill-sugarforever-boring-video-studio-listenhub-tts ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
ListenHub-TTS · 文稿 → 音频 + 字幕
把一段口播文本变成「配音音频 + 时间轴准确的 SRT 字幕」。这是视频制作链路的上游:产物 narration-full.mp3 + narration.srt 直接喂给 producing-video skill 出片。
铁律:时间轴是字幕的命根。 字幕的时间戳要准——这是这步唯一不能错的东西;个别错的中文同音字/英文专名,下游文本级校正只改字、绝不动时间轴。
分工
| 谁 | 做什么 | |---|---| | 用户 | 写口播稿(纯文本 narration.txt) | | 本 skill(你) | ListenHub 出音频 + 字幕(原生优先,ASR fallback)→ 编排校正 → 交出 mp3 + SRT | | 下游 | producing-video 拿 mp3 + SRT 出成片 |
> 用户已经自己有音频/字幕 → 跳过本 skill,直接用 producing-video。本 skill 只在「只有文本」时补这一段。
两条出字幕的路(脚本自动选)
| | speech(默认/首选) | asr(fallback) | |---|---|---| | 端点 | 原生 POST /v1/speech(把文稿切句成多段 scripts) | OpenAI 兼容 /v1/audio/speech 出 mp3 + Whisper 转写 | | 字幕来源 | 引擎自带(subtitlesUrl)——文字=输入原文,零识别错 | ASR 听回去转写,会有同音字/专名错 | | 校正需求 | 几乎不需要(顶多规整标点/中英文空格) | 需要(Claude→Cloud 这类错) | | 要的 key | 仅 LISTENHUB_API_KEY | 还要 GROQ_API_KEY / OPENAI_API_KEY |
脚本默认走 speech;失败(或拿不到 subtitlesUrl)时,有 ASR key 就自动降级到 asr。TTS_MODE=asr 可强制走 fallback。
依赖检查(pre-flight)
command -v curl python3 # 两个都要;脚本纯标准库,无第三方依赖
command -v ffmpeg # 停顿插静音 + 1.1× 提速用;没装则跳过停顿(音频不停)
需要的 key(env,勿入库):
LISTENHUB_API_KEY—— 必须(,格式lh_sk_...)。GROQ_API_KEY或OPENAI_API_KEY—— 可选,仅 fallback(asr 路)时需要。
> 不依赖 listenhub CLI。 官方 marswaveai 有个 tts skill 走 listenhub CLI + 一整套 auth/config/shared 生态、且强交互;本 skill 刻意保持自包含 curl + 非交互,适合做自动化管道的上游。CLI 的 OpenAPI 模式读的也是同一个 LISTENHUB_API_KEY。
工作流
Step 0 · 选音色(speaker)
一个旁路、单声道叙述,选一个 speakerId。先列表再挑:
LISTENHUB_API_KEY=... scripts/listenhub-speakers.sh zh # 可读音色表(name·特征·描述)
LISTENHUB_API_KEY=... scripts/listenhub-speakers.sh zh --json # 原始 JSON,给 agent 解析
# 端点:GET /v1/speakers/list?language=zh,每个 speaker 有 speakerId/name/gender/profile
# (profile: styles/scenes/accent/description) + demoAudioUrl 试听
- 用
AskUserQuestion把候选音色端给用户挑(用name+ 性别/风格/适用场景,如「专业·解读」),拿到speakerId。用户不在意就用默认CN-Man-Beijing-V2(原野,沉稳磁性·叙事)。 - 适合 AI 解读/日更/科普的几个(已验证存在):
CN-Man-Beijing-V2原野(纪录片/有声书)、suzhe-45bbbe54苏哲(科普讲解/纪录片旁白)、liyan2-ef9401ec国栋(新闻播报/知识分享)、chat-girl-105-cn晓曼(女声·播客/知识分享)。demoAudioUrl可试听再定。 - ⚠️ 真实 speakerId 形如
suzhe-45bbbe54(不是猜的),务必从listenhub-speakers.sh zh的列表里取,别凭空编。 - 系列/日更沿用同一音色:这期用了哪个 speakerId,记下来,下期继续用,保持声音一致(和 producing-video 的品牌纪律一脉相承)。
- 选定的 speakerId 作 Step 1 脚本的第 3 个参数。
Step 0.5 · 多音字扫描(跑 TTS 前必做)
TTS 对多音字常选错读音 —— 典型:调用 的「调」该读 diào,裸「调」/上下文不清时引擎读成 tiáo(用户实际踩过)。所以在出音频之前,先扫一遍稿子:
scripts/scan-heteronyms.sh
它对照 heteronyms.md 的高危清单,把裸字 / 不在已知安全词里的多音字标 ⚠(在 调用/调试 这类词里的不标,通常没事)。对每个 ⚠,人工判断该读哪个音,按梯子修:
- ① 扩成无歧义的词(首选):
决定调哪个函数→决定调用哪个函数。改的是narration.txt,音频和字幕一起受益(speech 路字幕=输入原文)。 - ② 换种说法(扩词救不了时):有些字扩成词也错(「行」很硬,
一行仍可能读 xíng)→ 换词绕开(一句/单行)。 - ③ 漏到成片了 → 单句重生成 + 挖补换音轨(见 Gotcha「单句修音频」)。
> 不用引擎拼音 / SSML: ListenHub 原生 /v1/speech 无公开 SSML/拼音;且字幕=输入原文,标注会污染字幕 —— 文本改写对这个引擎严格更优。清单 heteronyms.md 遇新坑就加。 > 诚实限制: 发音没法从音频自动验证(ASR 转写出同一个汉字、分不出 tiáo/diào),这是预防不是保证,残余靠审听兜底。不是每个多音字都改,只在会选错时改。
Step 0.7 · 停顿 / 呼吸节奏(长稿建议)
内容一长、语音从头讲到尾,观众没时机消化,也不是真人博主的节奏。像博主那样在结构关节处留白 —— 在 narration.txt 里标停顿点,脚本会把标记剥掉再送 TTS(绝不会被念出来),在音频里插真实静音、SRT 时间顺延,视频呼吸空间零漂移地跟上(因为音频即时钟)。
两种标记(都单独成行):
- 空行 = 段落停顿,默认 0.8s(最常用:一个话题讲完就空一行)。
[停 X]= 显式停顿 X 秒;[停]////= 一个 0.8s 呼吸拍。同一间隙里显式标记优先于空行。
推荐时长(语义驱动,别均匀撒):
| 位置 | 时长 | 怎么标 | |---|---|---| | 章节 / 段落之间 | 0.8 - 1.2s | 空行(0.8)或 [停 1.2] | | 抛出关键数字 / 结论后 | 0.4 - 0.6s | [停 0.5] | | 转折前(「但是」「问题在于」) | 0.3 - 0.5s | [停 0.4] | | 句内、一个意思没说完 | 不停 | —— |
它去年还亏四点五亿。
但今年营收涨了四倍多。
[停 0.5]
还首次实现盈利。
- 机制:
buildreq解析标记 →--pause-map记「第 N 段后插 X 秒」;speech 主路出字幕后insert-pauses用 ffmpeg 在对应 cue 末尾拼静音 + 顺延 SRT。需要 ffmpeg(没装则跳过、音频从头讲到尾并提示)。 - 只在 speech 主路生效:ASR fallback 是整段合成 + Whisper 重分句、cue 与输入段不 1:1,本路只剥掉标记(不被念出)、不插停顿。
- 停顿加的是静音、不是内容,和「不注水」不冲突 —— 是把已有的话说出节奏。
- 之后若走 Step 2.5 的 1.1× 提速,停顿会随整体等比缩短(一起提速,正常)。
Step 1 · 出音频 + 原始字幕(一条脚本)
scripts/listenhub-tts.sh 默认走原生 speech 路:把文稿切句成多段 scripts(让自带字幕有逐句 cue)→ POST /v1/speech → 拿 audioUrl + subtitlesUrl → 下音频 + 把字幕规整成 SRT。
LISTENHUB_API_KEY=... [GROQ_API_KEY=...] \
scripts/listenhub-tts.sh [speakerId] [ttsModel]
# 出 /narration-full.mp3 + /narration.srt(原始,未校正)
- 第 3 参 = Step 0 选定的
speakerId(省略则用默认CN-Man-Beijing-V2)。 - 已验证的响应契约(2026-06):
{"code":0,"data":{"audioUrl":"…mp3","subtitlesUrl":"…srt","audioDuration":,"credits":N}}。subtitlesUrl直接是标准 SRT、逐句 cue、文字=输入原文(零识别错)。脚本递归提取 URL(穿透data包装层)、normalize直接吃这份 SRT。排查用--probe打原始响应。 - fallback(asr 路):
TTS_MODE=asr强制走;或 speech 失败时自动降级。ASR 提供方非交互用ASR_PROVIDER=groq|openai(默认 groq);Groqlarge-v3比large-v3-turbo略准,日更这个量级别为成本牺牲准确度,用完整版。
Step 2 · 字幕校正(你来编排,按此顺序)
先看走的是哪条路:
- speech 路(原生字幕):字幕文字 = TTS 的输入原文,没有识别错,通常可跳过校正(顶多让校正器规整一下标点/中英文空格)。先抽看几条,没问题就直接进 Step 3。
- asr 路(Whisper 转写):中文里的英文专名/同音字会有个别错(如 Claude→Cloud、Vercel→Verso),需要校正。
铁律仍是不动时间轴/编号/条数。 需要校正时,按此顺序:
- 先扫描可用的「字幕校正」skill,优先用它。 在当前 skill 列表里找名字含
subtitle/字幕/correction的(如subtitle-correction)。有就把原始 SRT 交给它修 —— 交互式、会问术语、质量更高、自带validate兜底。本项目不复制该 skill,只引用;README 注明需同时安装。 - 没有这类 skill → 先跟用户确认:「要用同一 ASR 提供方的 chat 模型做一次文本级校正吗?(只改文字、按原条目重挂时间戳,零时间轴风险)」。用户同意再跑:
``bash python3 scripts/srt_helper.py correct narration.srt narration.fixed.srt \ --base --key --model --terms "OpenAI, Anthropic, Claude, Vercel, ..." # Groq → base https://api.groq.com/openai/v1 · model llama-3.3-70b-versatile # OpenAI → base https://api.openai.com/v1 · model gpt-4o-mini # base/key 复用 Step 1 的 ASR 那套 ` srt_helper.py correct` 只把字幕文本发给 LLM、按原条目重挂时间戳/编号;LLM 出错或条数不符自动退回原始 SRT(零时间轴风险)。
- 校正完,若有
subtitle-correction的subtitle_tool.py,再validate兜底确认时间轴/条数/编号没变。
Step 2.5 · 提速(作者语速偏慢时,可选但常用)
不少作者口播偏慢,成片会显拖。交付前统一 1.1× 提速 + 响度规范化,音频和字幕一起处理:
# 音频:atempo 提速 + loudnorm 规范化(-14 LUFS)
ffmpeg -y -i narration-full.mp3 -af "atempo=1.1,loudnorm=I=-14:TP=-1.5:LRA=11" \
-c:a libmp3lame -q:a 2 narration-full.mp3
# SRT:所有时间戳按 1/1.1 缩放(否则字幕与画面全错位) —— 用 python 逐条 *1/1.1 重写
必须两件一起做:只提速音频不缩 SRT,字幕会越到后面偏得越离谱。 校验提速真生效:成片时长应 ≈ 原始 TTS 时长 ÷ 1.1(比值 ~1.10),不是原始时长。 倍率按人调(1.1 是慢速作者的常用起点;别盲目更快,咬字会糊)。
Step 3 · 交付
把 narration-full.mp3 + 校正后的 SRT 命名为 narration-full.mp3 + narration.srt,交给 producing-video skill(它会放进 audio/narration-full.mp3 + audio/narration.srt 进主流程)。
narration.txt ──(本 skill)──▶ narration-full.mp3 + narration.srt ──▶ producing-video ──▶ 4K MP4
成本(~3 分钟日更)
- TTS 是大头:ListenHub credits,~4 credits/分钟。
- 云端 ASR:~半美分到两美分,可忽略——且走 speech 路时根本不产生(自带字幕)。
- LLM 文本校正:~1 美分,可忽略——speech 路通常跳过。
- 走 speech 路只需 ListenHub 一家、一个 key,链路更短更省。
超出范围
- 声音克隆 / 「听起来像我」:本 skill 用通用音色。要克隆自己的声音,用支持克隆的云端 TTS(MiniMax / ElevenLabs)——克隆只换"出声那一步",下游字幕/时间轴/渲染不变。
- 出片:把音频 + 字幕变成视频是
producing-video的活,不在本 skill。 - 改时间轴的字幕重排:本 skill 的校正是纯文本级(条数/编号/时间戳一律不动)。需要重新切条/对齐 → 回到 ASR 或用专门工具。
Gotchas
- cue 粒度 = 每个
scripts段一条。已验证:输入按句切多段(脚本已做)→ 自带 SRT 就是逐句 cue、时间戳精确。所以切句别太粗(一段塞一大段话 → 一条长 cue,不利于切场景)。srt_helper.py normalize也能吃 VTT/JSON(秒/毫秒/时间戳串),但实测 ListenHub 回的就是标准 SRT。万一哪天粒度变粗,TTS_MODE=asr走 ASR 拿细粒度时间轴兜底。 - 时间轴 > 文字。要的是准时间戳;错字交给 Step 2 修,别为了"识别更准"去牺牲时间轴(重新分句会打乱 cue)。
- 校正绝不动时间轴/编号/条数。这是
subtitle-correction的铁律,本 skill 的srt_helper.py correct也照此实现(长度不符自动回退原始)。speech 路文字已是原文,通常无需校正。 - 优先用
subtitle-correctionskill,它质量更高、会问术语;srt_helper.py correct是没有该 skill 时的、需用户确认的回退方案。 - key 走 env,绝不入库。
LISTENHUB_API_KEY/GROQ_API_KEY/OPENAI_API_KEY都从环境变量读。 - 本地 whisper 的坑:
hyperframes transcribe -m large-v3当前是坏的(传--dtw large-v3,新版 whisper.cpp 要large.v3→unknown DTW preset)。云端 ASR 绕开此问题;若非要本地直调whisper-cli -osrt、别加--dtw。
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: sugarforever
- Source: sugarforever/boring-video-studio
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.