☰
Skills 仓库 elevenlabs-tts 技能实战:从配音脚本到 MP3/WAV 的本地语音画像工作流
2026/10/9 7:21:43 网站建设 项目流程

【免费下载链接】Skills

Agent skills for designers and builders using Codex, Claude, Cursor, and other AI coding agents

项目地址:https://gitcode.com/gh_mirrors/skills48/Skills
点击查看免费下载

本篇文章以 Skills 仓库中 elevenlabs-tts 技能的示例输入包 demo/input.md 为起点,完整讲解"配音脚本 → 本地语音画像 → ElevenLabs TTS 请求 → 音频交付"的端到端工作流。你将掌握语音画像 profiles.json 的配置格式、generate_voice.py 助手的全部命令行参数与参数解析优先级,以及如何在不暴露账号数据的前提下复用这一技能为任意项目生成旁白音频。

一、输入包:input.md 里的一次真实配音任务

input.md 是 elevenlabs-tts 技能的虚构示例输入包,全文只有三段,却完整定义了一次 TTS 生成任务所需的全部信息:

# Voiceover script Start with the overview. Open any project to see its activity, collaborators, and latest changes in one place. Voice: use the configured neutral product narrator. Output: MP3 and WAV.

拆解来看,这个输入包承载了三个信息维度:

  1. 旁白正文:即 "Start with the overview. Open any project to see its activity, collaborators, and latest changes in one place.",是实际要合成语音的文案,对应脚本的--text-file输入通道。
  2. 语音指令:"use the configured neutral product narrator"——使用已配置的中性产品解说员声音。这里的"已配置"指的就是本地语音画像(Local Profile)中预设的 voice,而不是在脚本里硬编码某个具体声音。
  3. 输出要求:"MP3 and WAV"——交付两种音频格式。

根据 demo/PROMPT.md 的说明,这个 input.md 被定位为 "fictional source packet"(虚构数据源包),用于在演示页 index.html 中与预期输出做"输入→输出"的对照展示,演示场景是 "Generate a clean product-tour voiceover from a short script."。这意味着 input.md 不仅是一段文案,更是验证整个技能工作流是否正确的标准输入。

二、技能定位与隐私边界:技能目录里不存任何账号数据

SKILL.md 开篇就明确了技能的核心定位:生成 ElevenLabs 语音合成音频,但保持技能的可复用性与非个人化(reusable and non-personal)。为此它立下了三条硬性约定:

  • 技能内不存储API Key、声音名称、voice id、邮箱、账号名、客户名或任何个人默认值;
  • API Key 只从环境变量或最近的.env文件读取(ELEVENLABS_API_KEY);
  • 账号专属的语音画像从技能外部的本地 JSON 配置读取,且生成时使用请求级(request-level)设置,除非用户明确要求,否则不修改 ElevenLabs 账号或语音的持久化设置。

从 generate_voice.py 的源码可以印证 API Key 的读取逻辑:load_env以os.environ为基础,再通过find_upward从当前工作目录逐级向上查找最近的.env文件(find_env_file,generate_voice.py),且setdefault保证已存在的进程环境变量优先于 .env 文件内容。主函数中一旦取不到ELEVENLABS_API_KEY,立即抛出Missing ELEVENLABS_API_KEY in the environment or nearest .env file.错误并退出(generate_voice.py)。

这套边界设计让技能可以被任何开发者直接复用:账号信息留在本地,技能与脚本保持纯净。

三、本地语音画像:profiles.json 配置格式与字段详解

语音画像(Local Profile)是技能的中枢。SKILL.md 给出了推荐的配置来源顺序:

  1. --config /path/to/profiles.json(命令行显式指定)
  2. ELEVENLABS_TTS_CONFIG=/path/to/profiles.json(环境变量)
  3. local/elevenlabs/profiles.json(用户主目录下的默认位置)

项目本地的画像文件(只要被 gitignore)同样可用,例如config/local/elevenlabs-tts.json。从源码resolve_config_path(generate_voice.py)可以还原实际的解析顺序:先取--config或ELEVENLABS_TTS_CONFIG的显式路径;否则从当前目录向上查找项目路径config/local/elevenlabs-tts.json(PROJECT_CONFIG_PATHS,查找过程在到达用户主目录时停止);最后回退到主目录的~/.local/elevenlabs/profiles.json。

配置文件的标准形状(来自 SKILL.md,可直接复制使用):

{ "default_profile": "default", "profiles": { "default": { "voice_name": "Voice name from the local account", "voice_id": "optional-direct-voice-id", "voice_id_env": "OPTIONAL_ENV_VAR_WITH_VOICE_ID", "model_id": "eleven_multilingual_v2", "output_format": "mp3_44100_128", "voice_settings": { "stability": 0.5, "similarity_boost": 1.0, "style": 0.0, "speed": 1.0, "use_speaker_boost": true }, "output_dir": "outputs/voiceovers", "emails": [] } } }

各字段的作用如下:

字段类型作用
default_profilestring未指定--profile/ELEVENLABS_TTS_PROFILE时默认选中的画像名
profilesobject画像集合,键为画像名,值为画像配置
voice_namestring本地账号中的声音名称;当没有voice_id时脚本会通过 API 搜索该名字
voice_idstring(可选)直接指定的 ElevenLabs 声音 id,优先于名称搜索
voice_id_envstring(可选)存放 voice id 的环境变量名;运行时从该环境变量读取
model_idstring语音模型,示例为eleven_multilingual_v2(多语言 v2 模型)
output_formatstring输出音频编码,示例为mp3_44100_128(44100Hz、128kbps 的 MP3)
voice_settingsobject请求级语音参数:stability(稳定性)、similarity_boost(相似度)、style(风格)、speed(语速)、use_speaker_boost(人声增强)
output_dirstring未指定--output时音频的落盘目录
emailsarray本地路由/上下文使用的元数据

SKILL.md 特别说明:emails、owners、aliases、notes 等字段只用于本地路由和上下文,脚本会忽略未知的元数据字段,因此可以在不破坏功能的前提下扩充自己的本地信息。

四、六步工作流

SKILL.md 给出了技能的完整工作流,共六步:

  1. 选择画像:按--profile→ELEVENLABS_TTS_PROFILE→ 配置中的default_profile的顺序决定使用哪个画像。
  2. 调用助手脚本(推荐路径):
    python3 <skill-root>/scripts/generate_voice.py --text-file script.txt --profile default --output output.mp3
  3. 解析声音:画像有voice_id则直接使用;有voice_id_env则读取该环境变量;两者都没有则通过voice_name调用 ElevenLabs 搜索。
  4. 应用生成参数:使用画像中的model_id、output_format、voice_settings,除非用户为本次生成显式覆盖。
  5. 落盘:音频写入用户指定的目标;未指定时先使用画像output_dir,最后回退到outputs/voiceovers/。
  6. 汇报:输出音频路径与重要警告,绝不打印密钥等敏感信息。

五、generate_voice.py:从脚本到请求的完整调用链

助手脚本 generate_voice.py 是这一技能的执行核心(纯 Python 标准库实现,无第三方依赖)。build_parser(generate_voice.py)注册了全部命令行参数:

参数说明
--text "..."直接传入要合成的内联文本
--text-file path.txt从 UTF-8 文本文件读取文案
(stdin)既无--text也无--text-file时,从标准输入读取
--profile name选择本地画像
--config path.json选择本地画像文件
--voice-id/--voice-name单次生成的 voice id / 声音名称覆盖
--model-id/--output-format单次生成的模型 / 输出格式覆盖
--settings-json本次生成的 voice_settings 覆盖(JSON 对象)
--output path.mp3指定输出文件路径
--env-file指定.env文件路径(默认从当前目录向上查找最近的.env)
--seed N可选的 ElevenLabs seed,尽力保证结果可复现
--dry-run只打印解析后的请求负载,不调用语音合成接口
--list-voices列出匹配的声音而不生成音频

5.1 文本输入三通道

read_text(generate_voice.py)按--text→--text-file→ stdin 的优先级取值:--text-file以 UTF-8 读取文件内容;若既无参数且 stdin 不是终端(tty),则从 stdin 读取;否则报错提示必须提供三者之一。读取后统一strip并拒绝空文本。

5.2 取值优先级:CLI > 环境变量 > 画像 > 内置默认

脚本用choose_value(generate_voice.py)实现统一的解析优先级。以 voice 解析为例(generate_voice.py):

  • voice_id:--voice-id→ 环境变量ELEVENLABS_TTS_VOICE_ID→ 画像voice_id_env指向的环境变量 → 画像voice_id;
  • voice_name:--voice-name→ELEVENLABS_TTS_VOICE_NAME→ 画像voice_name;
  • model_id:--model-id→ELEVENLABS_TTS_MODEL_ID→ 画像model_id→ 内置默认eleven_multilingual_v2;
  • output_format:--output-format→ELEVENLABS_TTS_OUTPUT_FORMAT→ 画像output_format→ 内置默认mp3_44100_128。

若最终 voice id 和 voice name 都为空,脚本会报错要求至少配置其一。

5.3 声音解析:精确匹配与歧义保护

当只有voice_name时,resolve_voice_id(generate_voice.py)调用GET /v2/voices并带search与page_size=100参数搜索:只接受名称完全一致(exact match)的结果;搜不到时报错并列出返回的候选名称;重名时则列出所有候选 voice id,提示用户显式设置voice_id消歧。这套设计避免了"模糊匹配到错误声音"的隐患。

5.4 请求体构造与参数合并

请求体payload(generate_voice.py)包含text、model_id,以及非空的voice_settings,可选seed。voice_settings的合并顺序(profile_settings,generate_voice.py)是:画像voice_settings作为基底 → 被环境变量ELEVENLABS_TTS_SETTINGS_JSON覆盖 → 再被命令行--settings-json覆盖(CLI 优先级最高)。

5.5 输出路径与命名

未指定--output时,default_output_path(generate_voice.py)在output_dir(画像output_dir优先,否则outputs/voiceovers)下生成{画像名或声音名}-{YYYYMMDD-HHMMSS}.mp3的时间戳命名文件;目录不存在时自动mkdir(parents=True)创建,音频以二进制写入并打印字节数(generate_voice.py)。

5.6 调试利器:--dry-run 与 --list-voices

--dry-run不调用合成接口,而是打印解析后的完整请求摘要:config_path、profile、voice_id、voice_name、resolved_voice_name、output、output_format与payload(generate_voice.py),非常适合在正式合成前核对画像与参数。--list-voices则以voice_id<TAB>voice_name的格式列出(可带--voice-name过滤)匹配的声音(generate_voice.py)。

5.7 错误处理与网络细节

所有 API 调用通过urlopen(timeout=90)完成(generate_voice.py):HTTP 错误会读取响应体并拼进ElevenLabsError(便于看到 API 返回的具体错误信息);网络不可达则附上reason。脚本统一以error: ...写入 stderr 并以退出码 1 结束(generate_voice.py)。

关于 MP3 与 WAV 双格式:从源码结构看,一次调用只解析一种output_format(默认mp3_44100_128),且api_audio固定以Accept: audio/mpeg请求音频(generate_voice.py)。因此 input.md 中"Output: MP3 and WAV"的要求,通常是通过两次调用分别指定不同输出格式与目标文件来实现的,这也是预期交付清单中"MP3 and WAV generated"的落地方式。

六、API 端点速查

SKILL.md 明确要求使用当前的 ElevenLabs 端点(带xi-api-key请求头传 API Key):

  • 声音搜索:GET https://api.elevenlabs.io/v2/voices(脚本中支持search与page_size查询参数)
  • 语音合成:POST https://api.elevenlabs.io/v1/text-to-speech/:voice_id?output_format=...(脚本通过api_audio发送 JSON 负载)

其中 GET 请求的Accept为application/json,POST 的Content-Type为application/json。对应实现分别位于 api_json 与 api_audio。

七、端到端示例:产品导览配音的完整交付

回到开头的 input.md。假设本地已配置好"default"画像(中性产品解说员声音,voice_settings稳定度等参数已调好),一次完整的配音交付流程是:

# 1. 核对画像解析结果(不产生实际 API 调用) python3 agent-skills/codex/elevenlabs-tts/scripts/generate_voice.py \ --text-file agent-skills/codex/elevenlabs-tts/demo/input.md \ --profile default \ --dry-run # 2. 正式生成 MP3 python3 agent-skills/codex/elevenlabs-tts/scripts/generate_voice.py \ --text-file agent-skills/codex/elevenlabs-tts/demo/input.md \ --profile default \ --output-format mp3_44100_128 \ --output outputs/voiceovers/product-tour.mp3 # 3. 如需 WAV 交付,以对应格式再次生成 python3 agent-skills/codex/elevenlabs-tts/scripts/generate_voice.py \ --text-file agent-skills/codex/elevenlabs-tts/demo/input.md \ --profile default \ --output-format pcm_44100 \ --output outputs/voiceovers/product-tour.wav

--dry-run会打印类似如下的解析摘要,方便在合成前确认画像与请求负载:

{ "config_path": ".../profiles.json", "profile": "default", "voice_id": "...", "voice_name": "...", "output": "outputs/voiceovers/default-20261008-194528.mp3", "output_format": "mp3_44100_128", "payload": { "text": "Start with the overview. Open any project to see its activity, collaborators, and latest changes in one place.", "model_id": "eleven_multilingual_v2", "voice_settings": { "stability": 0.5, "similarity_boost": 1.0, "style": 0.0, "speed": 1.0, "use_speaker_boost": true } } }

正式调用成功后,脚本会打印Wrote <路径> (<字节数> bytes)。对照 expected-output.md 中的音频交付清单,本次任务需逐项核验:

  • local voice profile resolved without exposing account data —— 本地语音画像解析完成且未暴露账号数据;
  • MP3 and WAV generated —— MP3 与 WAV 均已生成;
  • duration and file type verified —— 时长与文件类型已验证;
  • spoken copy checked for clipping and unintended pauses —— 已检查口播文案是否存在削波与意外停顿。

这套"输入包 → 处理 → 交付清单"的对照结构,正是 demo/index.html 演示页所呈现的 evidence-first 工作流参考(顶部标注 "Workflow reference · 01"),配合上文 preview.jpg 截图可以看到输入与预期输出左右对照的完整形态。

八、复用与扩展:让技能适配更多配音场景

demo/PROMPT.md 提供了技能复用的两种方式:

  • Minimal prompt:Use $elevenlabs-tts to create a polished standalone HTML example that clearly demonstrates the skill.——以最小提示触发技能生成演示页;
  • Remix prompt:在保持相同实现契约(响应式 390px–1440px、语义化 HTML、可见焦点态、reduced-motion、单文件内联 CSS/JS、仅本地相对资源路径、不暴露真实客户或账号数据)的前提下,替换主题、文案、配色与内容层级,生成新的演示。

配合画像配置中的emails、owners 等本地路由元数据(脚本自动忽略未知字段),可以在不修改技能本体的情况下,为不同项目、不同客户分别维护专属语音画像。这使 elevenlabs-tts 成为一个既尊重隐私边界、又可在 Codex、Claude、Cursor 等 Agent 环境中反复调用的标准 TTS 能力。

【免费下载链接】Skills

Agent skills for designers and builders using Codex, Claude, Cursor, and other AI coding agents

项目地址:https://gitcode.com/gh_mirrors/skills48/Skills
点击查看免费下载
上一篇:微信聊天记录永久保存终极指南:如何让珍贵对话永不消失
下一篇:RxJS rx-lite-async 模块实战指南:用 start / startAsync / toAsync 将普通函数与 Promise 桥接进 Observable 世界

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询