ElevenLabs API 接入 Ofox:生成第一段配音,保存并验证音频
用 Python 或 cURL 接入 Ofox ElevenLabs API,生成并验证第一段真实 MP3。附模型与音色配置、可下载脚本、响应检查和额度报错排查。
通过 Ofox 生成 ElevenLabs 配音,需要向 /v1/audio/speech 提交文本、Ofox API Key、模型 ID elevenlabs/eleven_v4、兼容的音色 ID 和音频格式。成功后保存二进制响应,再确认文件可以解码。文件名叫 speech.mp3,不代表内容就是音频:把错误 JSON 保存成 MP3,是接入时很容易忽略的问题。
本文使用 2026 年 10 月 10 日的真实请求。原创英文台词生成了 10.00 秒 MP3,随后通过 Scribe 转写核对。源码、原始音频和响应记录均可下载。这是一次已成功的 Ofox 网关调用,不是稳定性测试,也不表示 ElevenLabs 原生接口的全部功能都已由该路由开放。
最终要交付什么
完成后应得到可播放的配音、输入台词、不含密钥的请求配置和验证记录,而不是只有一条 HTTP 200。音频可以接入视频工程,也可以继续转成字幕。复现本例需要具有访问权限和可用余额的 Ofox Key,以及正常工作的上游路由;本例不需要另外填入个人 ElevenLabs Key。
示例使用已有音色 ID,没有注册新音色或克隆真人声音。后续如果使用与真人有关的音色,应另行核对授权和使用权。接口调用成功,不代表获得了模仿某个人或用于任意商业场景的许可。
下载完整工具包,其中包括 audio_api.py、comparison.txt、elevenlabs.mp3 和响应元数据。客户端从环境变量读取密钥,遇到失败会停止,不自动重复可能产生费用的 POST 请求。
ElevenLabs 实际生成音频
1. 准备工具和确定版本的台词
安装 Python、requests、FFmpeg 和 ffprobe。HTTP 调用本身只需要请求客户端;这里安装媒体工具,是为了把解码和时长核验纳入完成标准。
python3 -m pip install requests
ffmpeg -version
ffprobe -version
通过自己的密钥管理工具或私有环境配置设置 OFOX_API_KEY。不要将它写进源码、文章、截图或提交到仓库的 .env,也不要为了排错打印 Authorization 请求头。工具包直接读取已设置的环境变量。
第一次使用工具包里的原始文本:
A clear product video starts with a clear brief. Show the real interface, explain one useful task, and check the exported video before sharing it.
文件保存为 UTF-8。排查阶段先保持文本不变,避免同时修改音色、模型、格式和台词,导致无法判断哪个变化解决了问题。多语言项目应先审校每种语言的台词;翻译正确与语音生成成功是两个不同检查。
自己的台词要提前处理缩写、日期和品牌读音。例如写出完整日期,比含糊的数字日期更容易复核。具体发音仍要听最终音频,不能只看文本预览。本文没有声称未验证的情绪或发音控制参数可以经此网关直接使用。
2. 使用网关认可的模型和音色字段
| 字段 | 本次值 | 作用 |
|---|---|---|
model | elevenlabs/eleven_v4 | 带供应商前缀的 Ofox 模型 ID |
voice | JBFqnCBsd6RMkjVDRZzb | 本次成功使用的音色标识 |
response_format | mp3_22050_32 | 请求的 MP3 预设,不是文件名 |
speed | 1.0 | 提交的速度值,不保证固定时长 |
变更前先查ElevenLabs 模型页。不要把显示名称当模型 ID,也不要把其他厂商的音色名直接填进来。
Ofox 网关和 ElevenLabs 原生接口并非同一个协议入口。原生示例可能把音色放在 URL 路径里,或支持更多专用参数;本文使用 Ofox 地址,并将音色放进 JSON 的 voice 字段。把原生文档的全部参数复制过来,不等于完成兼容性验证。
先用最小配置成功,再逐项尝试其他音色、语言参数和设置。封装统一客户端时,保留供应商特有配置,避免向使用者暗示所有语音模型可以无差别互换。
3. 用 Python 生成第一份 MP3
在解压后的工具包目录运行:
python3 audio_api.py speech \
--engine elevenlabs \
--text comparison.txt \
--output my-first-voiceover.mp3
请选择新文件名。客户端发现目标已存在会拒绝覆盖,以免第二次实验抹掉第一次的证据。它会保存不含密钥的内容配置,检查响应类型、写入音频、测量时长并尝试解码。预期得到 MP3 和元数据,而不是一个包含下载链接的 JSON。
本次返回 HTTP 200、audio/mpeg,文件 40,456 字节,ffprobe 测得 10.00 秒;客户端记录耗时 2.861 秒。耗时包含这一次网络和处理过程,不是首段音频延迟,也不是服务性能保证。
这里是真实生成的配音。保留原文件;如果为视频调整响度或裁剪静音,另存编辑版本,方便复查 API 最初返回了什么。
4. 用 cURL 复现同一请求
下面是另一种调用方式,先写临时响应,只有 HTTP 成功才改名:
python3 - <<'PY'
import json
from pathlib import Path
payload = {
'model': 'elevenlabs/eleven_v4',
'voice': 'JBFqnCBsd6RMkjVDRZzb',
'input': Path('comparison.txt').read_text().strip(),
'response_format': 'mp3_22050_32',
'speed': 1.0,
}
Path('speech-request.json').write_text(json.dumps(payload))
PY
curl --fail-with-body --silent --show-error \
https://api.ofox.ai/v1/audio/speech \
-H "Authorization: Bearer $OFOX_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @speech-request.json \
--output speech-response.tmp \
&& mv speech-response.tmp curl-voiceover.mp3
Python 和 cURL 二选一即可,两种都运行会发起两次生成。本文实测文件来自 Python 客户端,cURL 展示等价请求构造。旧版 cURL 如果不支持 --fail-with-body,使用 Python 客户端,或自行明确检查状态码。
失败后临时文件可能保留错误内容,先读取再处理。不要为了让播放器打开文件,直接把错误响应改成 .mp3。
5. 验证文件,而不只看状态码
ffprobe -v error -show_entries \
stream=codec_name,sample_rate,channels:format=duration \
-of json my-first-voiceover.mp3
ffmpeg -v error -i my-first-voiceover.mp3 -f null -
无解码错误只是技术检查,不能证明品牌读音、停顿、语气和画面切点都正确。发布前应完整试听,对照已经批准的台词,记录具体问题位置。
本例后续的 Scribe 转写 返回了相同词句,标点略有差别。这可以辅助检查,但不能替代试听:识别模型可能规范化某些错误,也可能漏掉杂音,两个模型结果相符并不等于音频完美。
验收记录至少包括台词版本、模型、音色、格式、实际时长、解码结果和发音检查状态。尚未检查的项目明确留空。HTTP 成功但内容未经确认,只能算进入编辑复核,不能直接当成可投放成品。
6. 按真实时长接入视频
以实际测量安排镜头。换音色或重新生成,同一台词也可能出现不同时长;speed=1.0 不会保证任何结果都适配十秒时间线。
旁白长于画面时,调整对应镜头或台词;短于画面时,可以保留有意的停顿。不理解 shortest 选项行为时,不要用它掩盖时长冲突,否则可能截掉结尾画面或最后几个字。
视频配音教程介绍测量、组装 MP4;Scribe 字幕教程介绍真实词级时间戳。这个样例证明指定配置可以得到音频,不证明所有语言、专业词和交付格式都同样适用。
7. 费用要区分计量单位
按字符、音频 token 和转写秒数计费,不是同一种单位,不能直接比较裸数字。以模型页、适用配置及账户的逐请求账单为准。
文件 40 KB、请求耗时约三秒,都不能推出本次实际收费。工具包保留请求信息,供使用者匹配自己的用量记录;本文没有把目录估算写成已结算账单。
批量制作时还要计入废片和重试。三次生成才得到一段可用配音,与一次通过的成本不同。应记录全部计费调用,再计算每份合格成品的费用,不能只凭最低牌价决定方案。
8. 按失败阶段排查
| 现象 | 先核对 | 处理 |
|---|---|---|
| 401 提到 quota | 错误正文、请求 ID | 核对实际路由和账号,不直接认定 Ofox 钱包空了 |
| 401 提到凭据 | 环境变量、认证方式 | 修正密钥来源,不打印密钥 |
| 400 或格式不支持 | 模型、音色、格式组合 | 回到已验证配置,一次改一个参数 |
| 很小的 MP3 播不了 | 响应类型与内容 | 先读错误,修好后再生成 |
| 超时且结果未知 | 请求记录 | 确认是否已完成再重试 |
| 漏词或读音不合适 | 原音频与台词 | 修订后另存新版本 |
此前本项目确实遇到 Ofox 钱包有余额、上游仍返回额度错误的情况;路由恢复后新请求成功。这只是相关请求的证据,不代表所有 401 都是同一原因。
常见问题
- 这里要填写 ElevenLabs 的 Key 吗?
- 不用。本例用 Ofox API Key 认证 Ofox 网关,ElevenLabs 原生接口是另一种接入方式。
- 可以任意填写音色名称吗?
- 不能假定都可以。本次成功使用正文给出的精确音色 ID,更换显示名称或其他厂商音色前要核对兼容性。
- 为什么 MP3 里是 JSON?
- 通常是客户端未检查状态码和响应类型,直接保存了错误正文。先处理错误,改扩展名不能修复音频。
- HTTP 200 就可以发布配音了吗?
- 还需要解码、时长和完整试听检查,核对漏词、发音与画面时间线,再决定是否发布。


