Whisper API 的基本调用并不复杂:一个 POST 请求、一个音频文件、一把 Key,就能拿到转写文本。真正消耗时间的是细节——文件超过 25 MB、格式不被接受、时间戳拿不到、长音频切分后时间轴错位。

本文按接入顺序讲清楚 endpoint 与鉴权、格式和大小限制、转写与翻译的区别、时间戳参数、curl 与 Python 两种调用方式、长音频切分、常见报错,最后给一份迁移清单。

说明:OpenAI、Whisper 是其权利人的商标,本文仅作技术接入说明,与 OpenAI 无隶属关系。接口能力、文件限制与计费口径可能调整,以官方文档和站内文档为准;价格以站内模型价格为准。示例中的网关是否完整支持音频接口,以站内文档为准。

一、先确认 endpoint 与鉴权

音频接口和对话接口不在同一个路径。转写用 /v1/audio/transcriptions,翻译用 /v1/audio/translations,都是 POST,请求体是 multipart/form-data,不是 JSON。鉴权沿用 OpenAI 风格的 Bearer Token。

项目 说明
转写 endpoint POST /v1/audio/transcriptions
翻译 endpoint POST /v1/audio/translations
鉴权头 Authorization: Bearer <API_KEY>
请求类型 multipart/form-data
官方 Base URL https://api.openai.com/v1
网关 Base URL https://ai.zhongshangqihang.com/v1,音频接口支持范围以站内文档为准

Key 只放在服务端。浏览器、App 或公开仓库里出现 Key,等同于把账户交出去。不同网关对音频接口的转发范围不一样,接入前先在模型价格或站内文档确认模型是否可用。

二、支持格式与 25 MB 限制

官方列出的输入格式是 mp3、mp4、mpeg、mpga、m4a、wav、webm,单文件上限 25 MB。flac、ogg 等格式不要想当然,先转码再上传。

25 MB 是文件大小限制,不是时长限制。码率越高,同样大小能装下的时长越短:16 kHz 单声道 mp3 可以装很久,48 kHz 立体声 wav 可能十几分钟就超限。上传前统一转成 16 kHz、单声道、mp3 或 wav,是最稳的预处理方式。

三、转写与翻译不是一回事

/audio/transcriptions 把音频转成原语言文本,中文音频输出中文;/audio/translations 把音频翻译成英文,官方文档明确只支持翻译成英文,且使用 whisper-1。需要中文字幕时用转写,不要指望翻译接口。

语言参数用 ISO-639-1 代码,例如 zh、en、ja。不传时模型自动识别,但短音频、中英混杂或口音较重时容易误判。明确业务语言时,显式指定更稳。

四、curl 最小示例

curl "https://ai.zhongshangqihang.com/v1/audio/transcriptions" \
  -H "Authorization: Bearer $WHISPER_API_KEY" \
  -F "file=@meeting.mp3" \
  -F "model=whisper-1" \
  -F "language=zh" \
  -F "response_format=verbose_json" \
  -F "timestamp_granularities[]=segment"

注意三点:文件字段用 -F;timestamp_granularities[] 要带方括号;只有 verbose_json 才返回分段结构。若网关未开放某个参数,先去掉再测,逐步定位。

五、Python 调用与时间戳

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["WHISPER_API_KEY"],
    base_url="https://ai.zhongshangqihang.com/v1",
)

with open("meeting.mp3", "rb") as f:
    result = client.audio.transcriptions.create(
        model="whisper-1",
        file=f,
        language="zh",
        response_format="verbose_json",
        timestamp_granularities=["segment"],
    )

for seg in result.segments:
    print(f"{seg.start:.1f}-{seg.end:.1f}  {seg.text}")

时间戳分两级:segment 是句段级,适合字幕和会议纪要;word 是词级,适合逐字对齐。官方文档说明 timestamp_granularities[] 目前只对 whisper-1 生效,且需要 verbose_json。较新的转写模型在准确率上可能更好,但时间戳和字幕格式的支持范围不同,选型前先看文档。

专有名词多的场景,可以用 prompt 传入人名、产品名和术语。官方文档说明 whisper-1 的提示词上限是 224 token,超出可能被截断,所以只放最关键的词。

只要文本时,response_format 用 json 或 text;做字幕文件可以直接要 srt 或 vtt。格式越多,响应体越大,批量场景下要衡量带宽和解析成本。

六、长音频先切分再转写

超过 25 MB 的音频必须切分。推荐流程:

  1. 用 ffmpeg 统一转成 16 kHz 单声道,降低体积。
  2. 按静音检测或固定 10 分钟切段,避免在句子中间下刀。
  3. 记录每段的起始偏移量,例如 part_000 对应 0 秒,part_001 对应 600 秒。
  4. 逐段调用转写接口,保存原始响应。
  5. 合并文本时把每段的时间戳加回偏移量。
  6. 在切点附近抽样校对,处理重复词和丢字。

段与段之间可以留 0.5–1 秒重叠,减少边界丢词,但重叠部分会被重复转写,合并时必须去重。切分脚本要同时保存偏移量清单,不要靠文件名猜时间;文件名、顺序和偏移量对不上,是合并阶段最常见的事故。并发能缩短总耗时,但不要超过账户的速率限制,否则 429 重试反而拖慢整体进度。

七、常见报错怎么排查

  • 401:Key 错误、过期,或没有带 Bearer。
  • 404:Base URL 或路径写错,确认是 /v1/audio/transcriptions。
  • 400:格式不支持、参数拼写错误,或模型不支持该参数。
  • 413:文件超过大小限制,压缩或切分。
  • 429:并发或额度超限,降并发并按指数退避重试。
  • 5xx 或超时:服务端或网络问题,限制重试次数,避免重复计费。
  • 返回空文本:音频静音、音量过低或语言误判,先检查音频并指定 language。
  • 没有时间戳:response_format 不是 verbose_json,或模型不是 whisper-1。

八、从官方切到网关的迁移清单

  1. 确认目标网关的 Base URL 和音频接口路径。
  2. 确认要用的模型在站内可用,名称与官方一致。
  3. 把 JSON 请求体改成 multipart/form-data。
  4. 对齐 response_format,检查代码是否依赖 segments 字段。
  5. 验证时间戳参数是否被支持,不支持就退回到句段级或本地对齐。
  6. 设置合理的超时和最大重试次数。
  7. 日志里不要记录完整音频地址和 Key,文本结果按敏感数据管理。
  8. 用一组真实业务音频做回归,比较字错率和时间轴。
  9. 准备降级路径:换模型、换区域,或退回官方接口。

常见问题

Whisper API 和开源的 Whisper 模型有什么区别?

开源模型可以自己部署,数据留在本地,但要承担显卡、运维和调优成本。托管 API 省去部署,按使用量计费,适合快速上线和波动流量。

25 MB 是音频时长限制吗?

不是,是文件大小限制。降低码率、转单声道可以显著延长可上传时长;超过限制就切分。

为什么拿不到词级时间戳?

词级时间戳需要 whisper-1、verbose_json 和 timestamp_granularities=["word"] 同时满足。换模型或换格式都可能导致字段缺失。

翻译接口能把英文翻成中文吗?

不能。官方翻译接口只输出英文。中文场景应使用转写接口,再用文本模型做翻译。

网关能直接替换官方 Base URL 吗?

文本接口通常可以,音频接口要看网关是否转发对应路径和参数。接入前用短音频做一次完整验证,不要默认兼容。

下一步

先注册中商起航 AI 网关,创建测试 Key,用一段一分钟音频跑通转写,再验证时间戳和长音频切分。模型与价格以模型价格为准。

相关阅读: