转录 API 的报错分别代表什么
对接很少出问题,但出问题总在最不合适的时候。好消息是:转录的错误来源就那么几种,多数一分钟能修好。下面按顺序讲,并说明哪些值得自动重试。
状态码对照表
| 状态码 | 发生了什么 | 怎么办 |
|---|---|---|
| 401 | 密钥错误、已撤销或根本没送到 | 检查 Authorization 头和密钥本身 |
| 400 | 文件为空、损坏或不是音频 | 用播放器打开确认,检查编码 |
| 413 | 文件超过体积上限 | 压成 opus 或切成几段 |
| 429 | 触发频率限制或余额用尽 | 降速,或者充值 |
| 502 | 识别后端临时不可用 | 稍等后重试 |
错误体沿用常见结构——带 message 和 type 的 error 对象,所以 SDK 的类型化异常照常工作。
401 多半出在请求头
按出现频率排列的三个原因:
- 密钥里混进了空格或换行,从邮件里复制时尤其常见。
- 少写了 Bearer:请求头必须是 Authorization: Bearer 你的密钥。
- 测试环境的密钥进了生产,或者反过来。
最快的排查方式是用一条 curl 试一下:能通就说明问题在代码里,而不在权限上。
429 有两种含义
同一个状态码,既可能是请求太密,也可能是分钟数用完了。看响应里的文字就能区分。前者靠队列和并发上限解决,后者靠充值。
一个好习惯:在后台盯着余额并提前设好提醒,而不是从生产日志里才发现。
怎么正确地重试
只有临时故障值得重试:429、502 和网络中断。400、401、413 重试一万次也是同样的答复——那是要修,不是要撞。
import time
from openai import OpenAI, APIStatusError, APIConnectionError
client = OpenAI(base_url="https://voicesscribe.com/v1", api_key="your key", max_retries=0)
def transcribe(path, tries=4):
delay = 2
for attempt in range(tries):
try:
with open(path, "rb") as f:
return client.audio.transcriptions.create(model="whisper-1", file=f).text
except APIStatusError as e:
if e.status_code not in (429, 500, 502, 503):
raise
except APIConnectionError:
pass
time.sleep(delay)
delay *= 2
raise RuntimeError("转录失败: " + str(path))
等待时间翻倍比重试次数更重要:它给服务留出恢复余地,也避免你一秒后又撞同一个限制。
用你自己的录音试一试。 注册只需一分钟,免费额度足够判断识别质量。
免费获取 API 密钥常见问题
失败的请求会扣分钟吗?
不会。只有成功处理的请求才计费,报错不消耗分钟数。
能正常播放的文件为什么返回 400?
多半是改过后缀:扩展名写着 mp3,里面却是别的容器。用 ffprobe 看一下真实格式,必要时重新编码。
怎么区分 429 是限速还是没余额?
看响应体里的提示文字。余额和扣费记录在后台随时可查。
要开启 SDK 自带的重试吗?
通常不用。自己写重试更可靠,因为你能决定重试哪些状态码、等多久。
相关阅读
- Python 语音转文字:从一个文件到可用脚本 — 十分钟搭好 Python 语音转文字:安装、第一个请求、响应格式怎么选、错误处理与并发加速,以及最浪费时间的几个坑。
- 一次请求装不下的录音怎么转录 — 几小时的录音如何处理:先压缩,再按停顿切分,并行处理各段,最后合并成带连续时间戳的完整文本。
- 如何为音频存档搭建批量转录流水线 — 转录上万条录音而不丢失任何一条:任务队列、并发控制、重试策略、崩溃后续跑,以及如何把账单控制在预期之内。