TAS — 文本与语音,双向处理 (Speakee API)
一个脚本处理两个方向:
- 文本 → 语音 (TTS): 40+ 种语言,100+ 种语音,自定义语音 UID, 长文本分块,多人对话模式,ffmpeg 拼接,音频质量检查。
- 音频 → 文本 (STT): 将任何音频/视频文件转录为文本,包含单词 时间戳和 SRT/WebVTT 字幕,自动处理长录音分块。
所有功能都由捆绑脚本完成 —— 切勿重复实现它,并且绝对不要安装任何东西(无需 whisper、torch、faster-whisper 或 pip):
<技能基础目录>/scripts/tas.py
典型安装位置:
~/.config/opencode/skills/tas/scripts/tas.py (opencode),
~/.claude/skills/tas/scripts/tas.py (Claude Code),以及
~/.agents/skills/tas/scripts/tas.py (skills CLI,npx skills add)。
该技能的名称为 tas —— 使用名称 tas 加载它,切勿使用 tts。
不可协商的规则 (适用于每次请求)
- 使用捆绑脚本。 不要为 TTS 或 STT 编写临时的 curl/python 片段。
- 绝不安装任何东西。 不要运行
pip install faster-whisper、pip install whisper、pip install torch,或下载任何模型。该 脚本完全通过 Speakee API 和 Python 标准库实现 STT —— 无需本地模型,无需本地下载,无需 pip。 - 交付前务必验证。
tts和conversation会自动运行音频 QA;QA: FAIL的结果必须修复,不得交付。 - 报告结果: 最终路径、时长、大小和 QA 状态 (TTS); 最终 SRT/VTT/文本路径和提示词数量 (STT)。
- 始终进行预检查。 在任何请求之前,语言、模型和语音都会被验证; 绝不发送猜测的语音。
- 保持缓存开启,除非用户另有要求。它能使重新运行变快,并恢复失败的对话。
- 绝不猜测语音名称。 使用
voices/suggest解析,或传入 UUID。 - 尊重免费 API: 默认
--workers 4;遇到 HTTP 429 时降低。 - 让脚本规范化文本。 Markdown、URL、HTML 和 emoji 默认被移除;
仅当用户想要原文时才使用
--raw。 - 绝不预先分割长文本。 脚本会在句子边界自动分块并合并。
- STT 中总是传递
-l <代码>,当已知语言时。自动检测不可靠 (Whisper 会混淆孟加拉语/古吉拉特语);对于正确的孟加拉语,需要-l bn。 - 当其他工具或脚本消费结果时,使用
--json。
命令
| 命令 | 用途 |
|---|---|
tts | 合成一段文本 (TTS) |
uid | 使用自定义语音 UID 合成 (language=uid) |
conversation | 多说话人对话 → 一个拼接并验证过的 MP3 |
stt | 转录音频/视频文件 → 文本 (+ 可选 SRT/VTT) |
transcribe | stt 的别名 |
subtitle | 转录并生成 SRT 文件 |
verify | 对任何文件运行音频 QA |
voices -l <代码> | 列出某种语言的语音 |
suggest -l <代码> | 列出带推荐标记的语音 |
presets | 列出内置语音预设 |
languages | 列出支持的语言 |
models | 列出模型 (sonic-3.5 默认) |
cache-clear | 删除合成缓存 |
工作流程 A — 文本转语音 (TTS)
步骤 1 — 范围界定
确定:语言 (或让自动检测工作)、语调 (新闻 / 故事 / 助手 /
有声书)、单说话人或对话、期望的输出路径,以及是否需要字幕 (--srt) 或元数据 (--title/--artist)。
步骤 2 — 选择语言和语音
python3 "$S" languages # 43 个代码
python3 "$S" suggest -l bn # 首先推荐语音
python3 "$S" presets # 精心策划的语音集
如果用户有自定义语音 UID,使用 uid 模式。否则,优先选择预设或推荐语音,而不是默认值。
步骤 3 — 合成
单说话人:
python3 "$S" tts "আপনার টেক্সট" -l bn -o out.mp3
python3 "$S" tts --text-file article.md -l en --preset news -o article.mp3
对话:
python3 "$S" conversation dialog.txt -l bn \
--map "মানুষ=Nayem,AI=Pooja - Everyday Assistant" \
--loudnorm --srt dialog.srt -o dialog.mp3
对于长或昂贵的运行,先使用 --dry-run。
步骤 4 — 验证
QA 自动运行。要重新检查任何文件:
python3 "$S" verify out.mp3
检查项:解码、时长、集成响度 (ebur128)、真峰值/削波、以及前导/尾部/内部静音。退出码 5 表示失败。
步骤 5 — 交付
报告:
out.mp3 — 2.8s, 0.04 MB, QA 通过 (-18.9 LUFS, 峰值 -4.2 dBFS)
除非被要求,否则不要粘贴原始 JSON。
步骤 6 — 重复使用
重新运行会命中缓存 (~/.cache/speakee-tas)。使用 --force 重新生成,
cache-clear 清除缓存。
工作流程 B — 语音转文本 (STT)
当用户有音频或视频文件并想要转录文本、字幕、隐藏式字幕或 SRT 文件时使用此流程。不要安装 Whisper —— 捆绑脚本直接调用 Speakee /api/stt 端点。
步骤 1 — 确认文件
python3 "$S" verify /path/to/audio.mp3 # 可选:确认文件可解码
ls -la /path/to/audio.mp3
步骤 2 — 选择语言
# 自动检测 (不可靠 — Whisper 会混淆孟加拉语/古吉拉特语):
python3 "$S" stt audio.mp3
# 当已知语言时,总是优先使用显式语言:
python3 "$S" stt audio.mp3 -l bn
重要: 为正确的文字传递 -l <代码>。对于孟加拉语使用
-l bn;自动检测会为孟加拉语音频返回古吉拉特语。低置信度
(< 0.5) 警告意味着检测到的语言可能错误。
步骤 3 — 转录 + 生成字幕
# 在输入文件旁边写入 SRT + VTT,并保存转录文本:
python3 "$S" stt audio.mp3 -l bn \
--srt --srt-path audio.srt --vtt --vtt-path audio.vtt \
-o audio.txt
# 简写:仅生成 SRT (subtitle 命令):
python3 "$S" subtitle audio.mp3 -l bn -o audio.srt
# 机器可读的 JSON (用于其他工具):
python3 "$S" stt audio.mp3 -l bn --json -o result.json
# 长录音:自动分块约 120s;强制更小的分块或一次上传:
python3 "$S" stt audio.mp3 -l bn --chunk-seconds 60
python3 "$S" stt audio.mp3 -l bn --no-chunk # 仅当文件小于约 3.5 MB
步骤 4 — 交付
报告:
audio.srt — 111 条提示 (8.05 分钟, 孟加拉语)
audio.txt — 转录文本已保存
STT 标志:--srt, --srt-path, --vtt, --vtt-path, --no-word-timestamps
(更快,时间估计), --chunk-seconds, --no-chunk, --workers,
--max-chars, --max-line-seconds。
对话模式 (TTS)
脚本格式,每行一个话轮:
演出开始了。 <- 无 "Speaker:" 前缀 -> 叙述者语音
মানুষ: ভাই, ২+২ কত?
AI: আপনার প্রশ্নটি গ্রহণ করা হয়েছে।
- 说话人标签是
:前的简短令牌 (≤16 个字符, 无空格)。 - 没有
Speaker:前缀的行是叙述者/评论者。叙述者通过特殊键narrator映射, 因此第三个不同的语音是--map "narrator=VoiceC,মানুষ=VoiceA,AI=VoiceB"。 --map "speaker=voice"接受语音名称 (模糊匹配) 或 UUID。- 如果没有
--map,会自动分配不同的语音。 - 语音必须不同。 如果两个说话人解析到同一个语音,脚本会打印
WARNING;将每个说话人映射到不同的语音。始终为 AI 和人类分配不同的语音 (当存在评论者/叙述者行时,还为叙述者分配第三种语音)。 --silence 0.35话轮之间的间隙;--loudnorm归一化到 −16 LUFS。--manifest FILE记录每个片段;--srt FILE写入字幕。--no-stitch保留单个片段文件而不是一个 MP3。--workers控制并行请求 (默认 4)。
选项 (最常用)
| 标志 | 默认值 | 含义 |
|---|---|---|
-l, --language | 自动检测 | ISO 代码或 uid |
-m, --model | sonic-3.5 | sonic-3.5 / sonic-3 / sonic-turbo / sonic-2 |
-v, --voice_id | 预设/默认 | 语音名称或 UUID |
-o, --out | 自动 | 输出文件 / 目录 (--no-stitch) |
-s, --speed | 1.2 | 0.5–2.0 |
--preset | — | news, story, assistant, audiobook |
--chunk-limit | 1200 | 每次请求的字符数 |
--retries | 4 | 带指数退避的重试次数 |
--workers | 4 | 并行请求数 |
--no-cache / --force | 关闭 | 绕过缓存 / 重新生成 |
--no-verify | 关闭 | 跳过自动 QA (不推荐) |
--dry-run | 关闭 | 打印计划,不发起请求 |
--json | 关闭 | 机器可读的输出 |
STT 选项
| 标志 | 默认值 | 含义 |
|---|---|---|
-l, --language | auto | ISO 代码 (孟加拉语使用 bn) |
--chunk-seconds | 120 | 每次上传的音频秒数 |
--no-chunk | 关闭 | 一次请求 (最大约 3.5 MB) |
--workers | 2 | 并行上传数 |
--srt / --srt-path | 关闭 | 写入 SRT 文件 |
--vtt / --vtt-path | 关闭 | 写入 WebVTT 文件 |
--no-word-timestamps | 关闭 | 更快;字幕时间估计 |
--max-chars | 42 | 最大提示字符数 |
--max-line-seconds | 6.0 | 最大提示秒数 |
--timeout / --retries | 300 / 3 | 每次请求的超时 / 重试次数 |
缓存与安全
- 片段按内容哈希缓存到
~/.cache/speakee-tas;重新运行和重试自动继续。 - 临时拼接文件总是被删除;
--no-cache的临时目录在退出时清理。 - 响应被验证 (
Content-Type: audio/*+ MP3 头部),因此错误 JSON 永远不会被保存为音频。 - HTTP 429 遵循
Retry-After;5xx/超时使用指数退避重试;永久 4xx 立即失败并显示服务器消息。 - STT 完全使用 Python 标准库在进程中运行 —— 无需网络安装,无需模型下载,无需 pip。
- 退出码:
0正常,1错误,2用法错误,3验证错误,4网络/API 错误,5音频 QA 失败。
参考文件
references/api.md— 端点、载荷、验证、重试、缓存。references/voices.md— 语言/语音目录、UID 模式、预设。references/troubleshooting.md— 症状、修复、常见故障模式。assets/presets.json— 精心策划的语音预设 (编辑以添加您自己的)。