mcpField
T
tts

tts

github.com/marswaveai创意与媒体811.4k 次安装5 周前更新
代码仓库

关于 tts

tts 是 ListenHub 的文本转语音技能,支持单人快速朗读和多角色脚本音频。它提供快速与脚本模式,并可通过配置管理音色分配和输出偏好。

主要功能

  1. 01单人快速语音生成
  2. 02多角色脚本音频生成
  3. 03按角色分配音色
  4. 04配置输出方式和语言偏好
  5. 05可选语速调整

适用场景

  1. 01朗读一段简短文本
  2. 02将标注说话人的脚本制作成对话音频

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/marswaveai/skills --skill tts

安装后在 Claude Code 中输入/tts确认已加载。

附带文件references/tts-guide.md

详细介绍

适用场景

  • 用户想将文本转换为语音
  • 用户要求“朗读”“TTS”“文本转语音”或“语音旁白”
  • 用户说“朗读”“配音”或“语音合成”
  • 用户想生成多角色脚本音频或对话

不适用场景

  • 用户想要带有主题探索的播客风格讨论(使用 /podcast)
  • 用户想制作带有视觉内容的讲解视频(使用 /explainer)
  • 用户想生成图片(使用 /image-gen)

用途

将文本转换为自然流畅的语音。分为两种模式:

  1. 快速模式(--mode direct):单一语音,低延迟、同步。适用于日常聊天、朗读短文和即时音频。
  2. 脚本模式(--mode smart):多角色,可为各片段分别指定语音。适用于对话、有声书和脚本内容。

硬性约束

  • 始终按照 shared/cli-authentication.md 检查 CLI 身份验证
  • 按照 shared/cli-patterns.md 执行 CLI 命令、处理错误并遵循交互模式
  • 绝不在 CLI 调用中硬编码发言者 ID——仅将 shared/speaker-selection.md 中的内置默认值用作备用;用户想更换语音时,应从 speakers CLI 获取
  • 进行任何交互前,始终按照 shared/config-pattern.md 读取配置
  • 始终按照 shared/speaker-selection.md 选择发言者(文本表格 + 自由文本输入)
  • 绝不将文件保存到 ~/Downloads/ 或 /tmp/ 作为主要输出——将生成文件保存到当前工作目录,并使用清晰、与主题相关的文件名(参见 shared/config-pattern.md § Artifact Naming)
每个多选步骤都必须使用 AskUserQuestion 工具——不得以纯文本形式列出选项。每次只提一个问题。等待用户回答后再进行下一步。收集完所有参数后,总结所选内容并请用户确认。在用户明确确认之前,不得调用任何生成 CLI 命令。

模式判定

在提问前,根据用户输入自动判定模式:

信号模式
“多角色”“脚本”“对话”“script”“dialogue”“multi-speaker”脚本
提及多个角色的姓名或身份脚本
输入包含结构化片段(A: …、B: …)脚本
单段文本,没有角色标记快速
“读一下”“read this”“TTS”“朗读”并附有纯文本快速
不明确快速(默认)

交互流程

步骤 -1:CLI 身份验证检查

按照 shared/cli-authentication.md 操作。如果未安装 CLI 或用户尚未登录,则自动安装并自动登录——绝不要求用户手动运行命令。

然后按照 shared/cli-authentication.md § Auth Mode Detection 确定 AUTH_MODE 并设置:

if [ "$AUTH_MODE" = "openapi" ]; then
  CMD_PREFIX="listenhub openapi tts"
else
  CMD_PREFIX="listenhub tts"
fi

后续所有 CLI 调用均使用 $CMD_PREFIX,而不是硬编码的 listenhub tts。

步骤 0:配置设置

按照 shared/config-pattern.md 步骤 0(零提问启动)操作。

如果文件不存在——静默创建默认配置并继续:

mkdir -p ".listenhub/tts"
echo '{"outputMode":"inline","language":null,"defaultSpeakers":{}}' > ".listenhub/tts/config.json"
CONFIG_PATH=".listenhub/tts/config.json"
CONFIG=$(cat "$CONFIG_PATH")

不得询问任何设置问题。 直接进入交互流程。

如果文件存在——静默读取配置并继续:

CONFIG_PATH=".listenhub/tts/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/tts/config.json"
CONFIG=$(cat "$CONFIG_PATH")
设置流程(仅在用户主动要求重新配置时运行)

仅在用户明确要求重新配置时运行。显示当前设置:

当前配置 (tts):
  输出方式:{inline / download / both}
  语言偏好:{zh / en / 未设置}
  默认主播:{speakerName / 使用内置默认}

然后询问:

  1. outputMode:按照 shared/output-mode.md § Setup Flow Question 操作。

  2. Language(可选):“默认语言?”

    • “中文 (zh)”
    • “English (en)”
    • “每次手动选择” → 保持 null

收集完答案后,立即保存:

NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}')
# Save language if user chose one (not "每次手动选择")
if [ "$LANGUAGE" != "null" ]; then
  NEW_CONFIG=$(echo "$NEW_CONFIG" | jq --arg lang "$LANGUAGE" '. + {"language": $lang}')
fi
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
生成速度

默认:1.0 倍速(原速)。绝不询问速度。

只有当用户明确要求加快或放慢朗读速度时,才传入 --speed — “慢一点”、“快一点”、“1.25 倍速”、“read it faster”。否则省略该标记。

  • 范围:0.5 到 2.0 之间的任意值,最多两位小数;这是连续范围,不是固定步长。
  • 常用值:0.5、0.75、1(默认)、1.25、1.5、2;0.85 或 1.35 等中间值也适用。
  • 含义:生成音频的语速,不是播放器的播放速度。
  • 对含糊的说法采取保守映射:“慢一点” → 0.85、“快一点” → 1.25、“慢很多” → 0.5、“快很多” → 1.75。用户指定的数字原样传入。

只有当速度不是 1 时,才在确认摘要中显示速度。

快速模式 — $CMD_PREFIX create --mode direct

步骤 1:提取文本

获取要转换的文本。如果用户尚未提供,请询问:

“你想让我朗读什么文本?”

步骤 2:确定音色

  • 如果已设置 config.defaultSpeakers.{language}[0] → 静默使用(跳至步骤 4)
  • 如果未设置 → 使用检测到的语言在 shared/speaker-selection.md 中的内置默认值(跳至步骤 4)
  • 只有用户明确要求更换音色时,才显示音色选择

步骤 3:保存偏好设置

用户明确选择新音色后(使用默认值时不执行):

Question: "Save {voice name} as your default voice for {language}?"
Options:
  - "Yes" — update .listenhub/tts/config.json
  - "No" — use for this session only

步骤 4:确认

Ready to generate:

  Text: "{first 80 chars}..."
  Voice: {voice name}
  Speed: {speed}x        # omit this line when speed is 1

Proceed?

步骤 5:生成

对于较短的文本,直接传入:

RESULT=$($CMD_PREFIX create --text "{text}" --mode direct --speaker "{name}" --lang {lang} [--speed {0.5-2.0}] --json 2>/tmp/lh-err)
EXIT_CODE=$?

if [ $EXIT_CODE -ne 0 ]; then
  ERROR=$(cat /tmp/lh-err)
  case $EXIT_CODE in
    2) echo "Auth error: run 'listenhub auth login'" ;;
    3) echo "Timeout: try --no-wait" ;;
    *) echo "Error: $ERROR" ;;
  esac
  rm -f /tmp/lh-err
fi
rm -f /tmp/lh-err

AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')

对于较长的文本,先写入临时文件(参见 shared/cli-patterns.md § 长文本输入):

cat > /tmp/lh-content.txt << 'ENDCONTENT'
Long text content goes here...
ENDCONTENT

RESULT=$($CMD_PREFIX create --text "$(cat /tmp/lh-content.txt)" --mode direct --speaker "{name}" --lang {lang} [--speed {0.5-2.0}] --json)
AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')

rm -f /tmp/lh-content.txt

步骤 6:呈现结果

从配置中读取 OUTPUT_MODE。按照 shared/output-mode.md 中的说明执行。

inline 或 both:将 audioUrl 显示为可点击链接。

呈现:

Audio generated!

在线收听:{audioUrl}

download 或 both:同时下载文件。按照 shared/config-pattern.md § 文件命名,根据文本内容生成主题 slug。

SLUG="{topic-slug}"  # e.g. "server-maintenance-notice"
NAME="${SLUG}.mp3"
# Dedup: if file exists, append -2, -3, etc.
BASE="${NAME%.*}"; EXT="${NAME##*.}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$AUDIO_URL"

呈现:

Audio generated!

已保存到当前目录:
  {NAME}

脚本模式 — $CMD_PREFIX create --mode smart

步骤 1:获取脚本

确定用户是否已提供脚本数组:

  • 已提供(JSON 或清晰的分段):解析并显示以供确认

  • 尚未提供:帮助用户整理分段。询问:

    “请提供包含说话人分配的脚本。格式:每行写成 SpeakerName: text content。我会为你转换。”

    用户提供脚本后,将其解析为带有说话人标注的文本。

步骤 2:为每个角色分配音色

对于脚本中的每个不同角色:

  • 如果 config.defaultSpeakers.{language} 中保存了音色 → 静默自动分配(按顺序为每个角色分配一个)
  • 如果未设置 → 使用 shared/speaker-selection.md 中的内置默认值(第一个角色使用 Primary,第二个角色使用 Secondary)
  • 只有用户明确要求更换音色时,才显示音色选择

步骤 3:保存偏好设置

分配完所有音色后(如果有新音色):

Question: "Save these voice assignments for future sessions?"
Options:
  - "Yes" — update defaultSpeakers in .listenhub/tts/config.json
  - "No" — use for this session only

步骤 4:确认

Ready to generate:

  Characters:
    {name}: {voice}
    {name}: {voice}
  Segments: {count}
  Speed: {speed}x        # omit this line when speed is 1
  Title: (auto-generated)

Proceed?

步骤 5:生成

使用说话人标记格式化脚本文本并提交。对于多说话人脚本,在文本中内联包含说话人名称。由于脚本模式可能耗时较长,请以 run_in_background: true 运行。

使用 --no-wait 提交(前台):

RESULT=$($CMD_PREFIX create --text "{formatted script with speaker markers}" --mode smart --speaker "{name1}" --speaker "{name2}" --lang {lang} [--speed {0.5-2.0}] --no-wait --json)
ID=$(echo "$RESULT" | jq -r '.id')
echo "Submitted: $ID"

对于较长的脚本,先写入临时文件:

cat > /tmp/lh-content.txt << 'ENDCONTENT'
SpeakerA: First line of dialogue
SpeakerB: Second line of dialogue
...
ENDCONTENT

RESULT=$($CMD_PREFIX create --text "$(cat /tmp/lh-content.txt)" --mode smart --speaker "{name1}" --speaker "{name2}" --lang {lang} [--speed {0.5-2.0}] --no-wait --json)
ID=$(echo "$RESULT" | jq -r '.id')

rm -f /tmp/lh-content.txt

使用 run_in_background: true 和 timeout: 600000 轮询(后台):

ID="<id-from-above>"
for i in $(seq 1 60); do
  RESULT=$(listenhub creation get "$ID" --json 2>/dev/null)
  STATUS=$(echo "$RESULT" | jq -r '.status // "processing"')

  case "$STATUS" in
    completed) echo "$RESULT"; exit 0 ;;
    failed) echo "FAILED: $RESULT" >&2; exit 1 ;;
    *) sleep 10 ;;
  esac
done
echo "TIMEOUT" >&2; exit 2

步骤 6:呈现结果

后台任务完成后,解析结果:

AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')
SUBTITLES_URL=$(echo "$RESULT" | jq -r '.subtitlesUrl // empty')
DURATION=$(echo "$RESULT" | jq -r '.audioDuration // empty')
CREDITS=$(echo "$RESULT" | jq -r '.credits // empty')

从配置中读取 OUTPUT_MODE。按照 shared/output-mode.md 中的说明执行。

inline 或 both:将 audioUrl 和 subtitlesUrl 显示为可点击链接。

呈现:

Audio generated!

在线收听:{audioUrl}
字幕:{subtitlesUrl}
时长:{audioDuration / 1000}s
消耗积分:{credits}

download 或 both:同时下载文件。按照 shared/config-pattern.md § 文件命名生成主题 slug。

SLUG="{topic-slug}"  # e.g. "welcome-dialogue"
NAME="${SLUG}.mp3"
# Dedup: if file exists, append -2, -3, etc.
BASE="${NAME%.*}"; EXT="${NAME##*.}"; i=2
while [ -e "$NAME" ]; do NAME="${BASE}-${i}.${EXT}"; i=$((i+1)); done
curl -sS -o "$NAME" "$AUDIO_URL"

呈现:

已保存到当前目录:
  {NAME}

更新配置

保存偏好设置时,合并到 .listenhub/tts/config.json 中,不要覆盖未更改的键。

  • 快速语音:将 defaultSpeakers.{language}[0] 设为所选的 speakerId
  • 脚本语音:将 defaultSpeakers.{language} 设为本次会话分配的完整数组
  • 语言:仅当用户明确指定时,才设置 language

API 参考

  • CLI 执行模式:shared/cli-patterns.md
  • CLI 身份验证:shared/cli-authentication.md
  • 说话人列表:shared/cli-speakers.md
  • 说话人选择指南:shared/speaker-selection.md
  • 配置模式:shared/config-pattern.md
  • 输出模式:shared/output-mode.md

可组合性

  • 调用:speakers CLI(用于选择说话人)
  • 由其调用:explainer(用于配音)

示例

快速模式:

“TTS this: The server will be down for maintenance at midnight.”

  1. 检测:快速模式(纯文本,“TTS this”)
  2. 读取配置:defaultSpeakers.en 为空
  3. 使用内置默认说话人:Mars(cozy-man-english)
  4. 确认 → 用户批准
  5. 生成:
    RESULT=$($CMD_PREFIX create --text "The server will be down for maintenance at midnight." --mode direct --speaker "Mars" --lang en --json)
    AUDIO_URL=$(echo "$RESULT" | jq -r '.audioUrl')
    
  6. 呈现:将 audioUrl 显示为链接(内联模式)

脚本模式:

“帮我做一段双人对话配音,A说:欢迎大家,B说:谢谢邀请”

  1. 检测:脚本模式(“双人对话”)
  2. 解析片段:A -> “欢迎大家”,B -> “谢谢邀请”
  3. 读取配置:defaultSpeakers.zh 为空
  4. 使用内置默认说话人:原野(主说话人)+ 高晴(次说话人)
  5. 确认 → 用户批准
  6. 生成:
    RESULT=$($CMD_PREFIX create --text "A: 欢迎大家
    B: 谢谢邀请" --mode smart --speaker "原野" --speaker "高晴" --lang zh --no-wait --json)
    ID=$(echo "$RESULT" | jq -r '.id')
    
  7. 在后台轮询,直到完成
  8. 呈现:audioUrl、subtitlesUrl、时长

评论

支持 Markdown