mcpField
O
openrouter-stt

openrouter-stt

github.com/openrouterteam生产力309255 次安装1 天前更新
代码仓库

关于 openrouter-stt

通过 OpenRouter 语音转文字端点转录音频的技能,说明如何以 JSON 提交 Base64 音频并选择模型,返回转录文本和用量信息。

主要功能

  1. 01以 JSON 提交 Base64 音频
  2. 02按完整标识选择转录模型
  3. 03设置语言和温度
  4. 04传递提供方专属选项
  5. 05读取转录文本及用量

适用场景

  1. 01转录录制的音频
  2. 02处理浏览器录制的音频
  3. 03向支持的提供方提供词汇提示

安装

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

$npx skills add https://github.com/openrouterteam/skills --skill openrouter-stt

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

附带文件README.md

详细介绍

OpenRouter 语音转文本

使用 curl 通过 POST /api/v1/audio/transcriptions 转录音频。需要 OPENROUTER_API_KEY(在 https://openrouter.ai/keys 获取)。如果未设置,请停止并询问。

此端点与 OpenAI 不兼容。 请求体是 JSON,音频以 base64 格式放在 input_audio: { data, format } 中,而不是像 OpenAI 的 /v1/audio/transcriptions 那样使用带有 file 字段的 multipart/form-data。不要让 OpenAI SDK 调用此端点;它会发送错误格式的数据。请直接使用 curl、fetch 或 requests。

一次调用,返回 JSON

请求和响应均为 JSON。响应正文包含:

  • text — 转录文本。
  • usage — 始终包含 cost。根据请求的计价方式,提供商还会报告音频计费时长(seconds)或 token 明细(total_tokens、input_tokens、output_tokens)。不要假设两者都会出现。

示例响应(按时长计价的提供商,例如 google/chirp-3):

{
  "text": "I used to rule the world.",
  "usage": {
    "seconds": 20,
    "cost": 0.005333
  }
}

示例响应(按 token 计价的提供商):

{
  "text": "Hello, this is a test of speech-to-text transcription.",
  "usage": {
    "total_tokens": 113,
    "input_tokens": 83,
    "output_tokens": 30,
    "cost": 0.000508
  }
}

即用型工作流

#!/usr/bin/env bash
set -euo pipefail

MODEL="google/chirp-3"
FORMAT="wav"                          # wav, mp3, flac, m4a, ogg, webm, aac
AUDIO="audio.wav"
BODY=$(mktemp)
PAYLOAD=$(mktemp)

audio_b64=$(base64 < "$AUDIO" | tr -d '\n')

jq -n --arg model "$MODEL" --arg data "$audio_b64" --arg fmt "$FORMAT" \
  '{model: $model, input_audio: {data: $data, format: $fmt}}' > "$PAYLOAD"

# --data-binary @file keeps the base64 payload off argv (avoids E2BIG / ARG_MAX).
http_code=$(curl -sS -X POST https://openrouter.ai/api/v1/audio/transcriptions \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  --output "$BODY" \
  -w '%{http_code}' \
  --data-binary @"$PAYLOAD")

if [[ "$http_code" != "200" ]]; then
  echo "STT failed (HTTP $http_code):" >&2
  cat "$BODY" >&2
  rm -f "$BODY" "$PAYLOAD"
  exit 1
fi

jq -r '.text' "$BODY"
rm -f "$BODY" "$PAYLOAD"

查找 STT 模型

按输出模态筛选模型端点,即可列出转录模型。

curl -sS "https://openrouter.ai/api/v1/models?output_modalities=transcription" \
  | jq '.data[] | {id, name, pricing}'

模型名称包含提供商命名空间 — 请使用完整的 slug(google/chirp-3、openai/whisper-1、openai/whisper-large-v3),而非短名称。

参数

字段必填说明
model是来自 /api/v1/models?output_modalities=transcription 的完整模型 slug。
input_audio.data是Base64 编码的原始音频字节。不是数据 URI — 仅使用 base64 负载,不要添加 data:audio/...;base64, 前缀。
input_audio.format是wav、mp3、flac、m4a、ogg、webm 或 aac。必须与实际字节匹配。支持情况因提供商而异。
language否ISO-639-1 代码(en、ja、fr)。省略时会自动检测。
temperature否0–1。数值越低,结果越稳定。
provider否提供商透传 — 见下文。
选择音频格式
  • wav / flac — 未压缩或无损格式。质量最高,上传文件也最大。
  • mp3 / m4a / aac — 压缩格式。负载更小;这很重要,因为在文件本身大小的基础上,base64 还会使字节数增加约 33%。
  • webm / ogg — 常用于浏览器录音(MediaRecorder)。

format 字段必须与字节的实际容器/编解码器匹配。一个以 .wav 保存、实际却是 mp3 的文件会被拒绝或错误解码。如有疑问,请使用 ffprobe <file> 确认。

提供商专属选项

提供商透传选项放在 provider.options.<slug> 下,且只有在该提供商处理请求时才会转发。示例 — Groq 用于词汇提示的 prompt:

{
  "model": "openai/whisper-large-v3",
  "input_audio": { "data": "UklGRiQA...", "format": "wav" },
  "provider": {
    "options": {
      "groq": {
        "prompt": "Expected vocabulary: OpenRouter, API, transcription"
      }
    }
  }
}

只有提供商匹配时,才会转发以提供商 slug 为键的选项;其他键会被忽略。请查看各提供商的上游文档,了解可用的透传键。

TypeScript(fetch)

import fs from "fs";

const audio = await fs.promises.readFile("audio.wav");
const data = audio.toString("base64");

const res = await fetch("https://openrouter.ai/api/v1/audio/transcriptions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "google/chirp-3",
    input_audio: { data, format: "wav" },
  }),
});

if (!res.ok) {
  throw new Error(`STT failed (HTTP ${res.status}): ${await res.text()}`);
}

const result = await res.json();
console.log(result.text);

Python(requests)

import base64
import os
import requests

with open("audio.wav", "rb") as f:
    data = base64.b64encode(f.read()).decode("utf-8")

res = requests.post(
    "https://openrouter.ai/api/v1/audio/transcriptions",
    headers={
        "Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "model": "google/chirp-3",
        "input_audio": {"data": data, "format": "wav"},
    },
)

if not res.ok:
    raise RuntimeError(f"STT failed (HTTP {res.status_code}): {res.text}")

print(res.json()["text"])

故障排除

text 乱码或为空——format 字段可能与实际字节不匹配,或者音频无声或已损坏。使用 ffprobe audio.wav 确认。

返回 400,并提示 "Invalid base64",或静默失败——data 必须只有 base64,不能是数据 URI(data:audio/wav;base64,...)。如果是从浏览器的 FileReader 复制的,请去掉前缀。

返回 400,并提示 ZodError——缺少必填字段,或字段类型错误。请求体格式如下:{"success":false,"error":{"name":"ZodError","message":"[...]"}}——其中嵌套的 message JSON 字符串会指出错误路径(常见的是 input_audio.data 或 input_audio.format)。

413 / 请求过大——base64 会使字节数膨胀约 33%,因此较大的原始文件会变成更大的 JSON 负载。请使用较小的源文件(压缩格式、较低采样率或裁剪后的片段)。

找不到模型——请使用 /api/v1/models?output_modalities=transcription 中的完整 slug(google/chirp-3,而不是 chirp-3)。

参考资料

评论

支持 Markdown