跳到正文
openrouter blog·· 21 天前精選AI 評分62

OpenRouter 語音生成 API 教學與實作指南

OpenRouter Text-to-Speech: API Tutorial in 5 Minutes

AI 導讀

OpenRouter 正式推出相容 OpenAI 的語音生成 (text-to-speech) API 端點,讓開發者透過單一 API 金鑰與統一的請求結構,就能存取多個提供者的 TTS 模型。

推薦理由

原文詳解透過 OpenAI 相容端點呼叫多個提供者語音模型的完整流程,工程師可直接參考程式碼實作串接與錯誤驗證。

正文 · AI 翻譯

我們透過 OpenAI 相容的 POST /api/v1/audio/speech 端點支援文字轉語音。傳送文字、模型與支援的聲音,然後儲存或串流音訊。單一 API 金鑰即可使用相同的請求結構,連結至 多個供應商 的 TTS 模型。

本教學涵蓋驗證、合成、回應驗證、串流,以及模型或聲音變更。

TL;DR

  • 將 TTS 請求送至 https://openrouter.ai/api/v1/audio/speech。
  • 透過將 base_url 設為 https://openrouter.ai/api/v1 來使用 OpenAI Python SDK。
  • 當模型支援其他聲音時,只需在一行內更改 voice 值。切換供應商時,請同時更改相應的模型與聲音。

Diagram showing a request with text, voice, and output format entering POST /api/v1/audio/speech, reaching the Mistral Voxtral Mini TTS model with xAI and Microsoft speech models as available alternatives, and returning one MP3 audio response

你在請求主體中指定模型。無論選擇哪個供應商的語音模型,端點、驗證與回應處理皆保持不變。

我們的 音訊 API 公告 覆蓋了更廣泛的發布。若要進行語音轉文字,請參考我們的 文字轉錄指南。

使用 OpenRouter 文字轉語音所需之專案

建立一個 OpenRouter API 金鑰,並將其存放於環境變數,以避免出現在您的程式碼中。

在 macOS 或 Linux 上,為目前的終端機會話設定變數:

export OPENROUTER_API_KEY="your-api-key"

所有範例皆以 https://openrouter.ai/api/v1 作為基礎 URL,並於 Authorization: Bearer 標頭 中傳送金鑰。

端點接受兩個必填欄位,外加大多數模型所需的聲音:

  • model 選擇語音模型。
  • input 包含你想讓模型說出的文字。
  • voice 選擇該模型所支援的聲音。除非供應商 說明有預設聲音,否則您只能省略它,實務上請視為必填。

response_format 與 speed 為可選項,但明確設定輸出格式可使回應更可預測,因為格式支援因模型而異。我們的端點預設為 PCM(若省略 response_format),而 Mistral Voxtral Mini TTS 僅接受 MP3,speed 只在支援的模型上改變說話速率。

成功的請求會回傳原始音訊位元組,而失敗的請求則回傳 JSON。請在寫入音訊檔前先驗證回應。

在瞭解金鑰與回應行為後,即可產生第一個音訊檔。

使用 cURL 產生第一個 MP3

以下請求使用 Mistral Voxtral Mini TTS 及其 en_paul_neutral 聲音,並將回傳的位元組直接儲存至 output.mp3。

curl --silent \
  --show-error \
  --fail-with-body \
  --request POST \
  --url https://openrouter.ai/api/v1/audio/speech \
  --header "Authorization: Bearer $OPENROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "mistralai/voxtral-mini-tts-2603",
    "input": "OpenRouter turns this text into speech through one API endpoint.",
    "voice": "en_paul_neutral",
    "response_format": "mp3"
  }' \
  --dump-header output.headers \
  --output output.mp3

這些旗標可協助你正確處理失敗請求。--fail-with-body 會在 4xx 或 5xx 回應時使 cURL 以錯誤退出,且因為設定了 --output,會將伺服器的 JSON 錯誤內容寫入 output.mp3 而非終端機。當命令失敗時,請使用 cat output.mp3 讀取錯誤並在重試前刪除該檔,以免將 JSON 檔當作音訊播放。--dump-header 儲存回應標頭,方便確認內容型別並取得產生 ID。

播放音訊前,請確認 output.mp3 存在且包含資料:

ls -lh output.mp3

在 macOS 上,你可使用 afplay output.mp3 播放;在 Linux 上,使用已安裝的播放器,例如 ffplay。

將此請求移入應用程式程式碼時,請確認請求成功且回應包含音訊,才將其儲存。此檢查可避免將 JSON 錯誤回應寫入 MP3 檔。

使用 Python 產生並儲存語音

若專案尚未使用,請安裝 requests:

python -m pip install requests

此範例會檢查 HTTP 狀態,並確認我們回傳 MP3 資料後再儲存檔案:

import os
from pathlib import Path

import requests

response = requests.post(
    "https://openrouter.ai/api/v1/audio/speech",
    headers={
        "Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "model": "mistralai/voxtral-mini-tts-2603",
        "input": (
            "OpenRouter turns this text into speech through one API endpoint."
        ),
        "voice": "en_paul_neutral",
        "response_format": "mp3",
    },
    timeout=60,
)

response.raise_for_status()

content_type = response.headers.get("Content-Type", "").split(";")[0]
if content_type != "audio/mpeg":
    raise RuntimeError(f"Expected audio/mpeg, received {content_type}")

Path("output.mp3").write_bytes(response.content)

generation_id = response.headers.get("X-Generation-Id")
print(f"Saved output.mp3. Generation ID: {generation_id}")

raise_for_status() 在 API 回傳 4xx 或 5xx 回應時會丟擲例外,避免應用程式將錯誤內容存成音訊。如果請求成功,content-type 檢查會確認回應包含音訊後再寫入檔案。記錄 X-Generation-Id 以便追蹤請求或在聯絡支援時提供參考。

相同的驗證規則也適用於 SDK 處理回應串流時。下一個範例保留 OpenRouter 的基本網址,並將檔案處理移至 OpenAI Python 客戶端。

使用 OpenAI Python SDK 進行回應串流

我們的 TTS 端點遵循 OpenAI Audio Speech API 的格式。您可以將 OpenAI 客戶端指向我們的基本網址,並將 HTTP 回應串流寫入檔案:

import os
from pathlib import Path

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["OPENROUTER_API_KEY"],
    base_url="https://openrouter.ai/api/v1",
)

with client.audio.speech.with_streaming_response.create(
    model="mistralai/voxtral-mini-tts-2603",
    voice="en_paul_neutral",
    input="OpenRouter can stream this response into an audio file.",
    response_format="mp3",
) as response:
    response.stream_to_file(Path("output.mp3"))

此模式會在儲存檔案時逐步讀取回應。漸進式播放需要使用可緩衝進來的區塊的播放器。

JavaScript 可以透過 arrayBuffer() 讀取相同的回應。此範例在建立檔案前先檢查狀態碼與內容型別:

import { writeFile } from "node:fs/promises";

const response = await fetch(
  "https://openrouter.ai/api/v1/audio/speech",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "mistralai/voxtral-mini-tts-2603",
      input: "OpenRouter returns audio bytes to JavaScript.",
      voice: "en_paul_neutral",
      response_format: "mp3",
    }),
  },
);

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

const contentType = response.headers.get("content-type")?.split(";")[0];
if (contentType !== "audio/mpeg") {
  await response.body?.cancel();
  throw new Error(`Expected audio/mpeg, received ${contentType}`);
}

await writeFile("output.mp3", Buffer.from(await response.arrayBuffer()));
console.log(response.headers.get("x-generation-id"));

若需要較小且能在標準音訊播放器播放的檔案,請選擇 MP3。PCM 避免了壓縮開銷,並可降低相容即時串流管線的延遲。我們以 audio/mpeg 回傳 MP3,以 audio/pcm 回傳 PCM,並可選擇加入 rate 與 channels 引數,儘管可用格式取決於所選模型。Mistral Voxtral Mini TTS 僅接受 MP3,若請求 PCM 將回傳 400 錯誤。播放原始 PCM 亦需正確的音訊設定,因為僅將檔案副檔名改為 .mp3 並不會轉換音訊格式。

傳輸程式碼在支援的模型間保持不變。model 與 voice 欄位必須保持有效配對。

更改 TTS 模型與聲音

聲音識別碼屬於特定模型。相同模型內的聲音比較可改變一行。舉例來說,現在的 Grok Voice TTS 1.0 model page 列出了五個內建聲音:eve、ara、rex、sal 和 leo。

從這個模型與聲音對開始:

"model": "x-ai/grok-voice-tts-1.0",
"voice": "eve"

接著只改變聲音行:

- "voice": "eve"
+ "voice": "ara"

Grok 範例亦示範了從 Mistral 轉換到 xAI 的供應商。因為每個供應商都有自己的模型與聲音 ID,請同時更新 model 與 voice,而端點、認證、輸入與回應檢查則保持不變:

- "model": "mistralai/voxtral-mini-tts-2603",
- "voice": "en_paul_neutral"
+ "model": "x-ai/grok-voice-tts-1.0",
+ "voice": "eve"

在送出請求前,請先在所選模型頁面確認兩個值,因為模型可用性與聲音目錄可能變更。

使用 Models API 取得目前的 TTS 模型:

curl "https://openrouter.ai/api/v1/models?output_modalities=speech"

您亦可瀏覽我們的 text-to-speech model collection。

模型 ID範例聲音顯著選項
mistralai/voxtral-mini-tts-2603en_paul_neutral透過 OpenRouter 語音端點輸出 MP3
x-ai/grok-voice-tts-1.0eve、ara、rex、sal、leo跨 20+ 種語言的五個內建聲音
microsoft/mai-voice-2en-US-Harper:MAI-Voice-2speed、Azure style 與 styledegree

我們的 TTS documentation 描述了您可透過 provider.options.<provider> for models that support them。到 2026 年 9 月為止,OpenAI 語音模型尚未列入即時目錄,請在依賴供應商特定欄位前確認目前模型清單。

Microsoft MAI-Voice-2 接受 Azure 聲音名稱。它亦支援 0.5 至 2.0 的已檔案化 speed 範圍與表現力豐富的 Azure 選項:

{
  "model": "microsoft/mai-voice-2",
  "input": "Welcome to the product update.",
  "voice": "en-US-Harper:MAI-Voice-2",
  "response_format": "mp3",
  "speed": 1.0,
  "provider": {
    "options": {
      "azure": {
        "style": "cheerful",
        "styledegree": 1.2
      }
    }
  }
}

這些控制項仍屬於供應商特定。未支援的供應商可能忽略 speed,樣式取決於所選聲音。請將供應商選項放在相應模型設定旁。

模型與聲音選擇決定可用的格式與表現力控制。生產流程必須在每次產生記錄時保留這些設定。

為生產環境準備整合

將長輸入按句子或段落邊界拆分,依序請求每個片段,並使用格式感知工具將音訊合併。這能提升可靠性並更快回傳第一個片段。

對每個片段套用相同的回應檢查:

  • 在非成功的 HTTP 狀態碼時停止。
  • 確認 Content-Type 與所請求的格式相符。
  • 拒絕空回應。
  • 以模型、聲音、格式和應用程式請求 ID 記錄 X-Generation-Id。
  • 在重試前分類回應,避免永久性請求失敗進入退避迴圈。

重試 429、502、503、524 和 529 回應,因為 速率限制、供應商錯誤、暫時不可用、逾時以及供應商過載可能在稍後嘗試時解決。若回應包含該標頭,請遵循 Retry-After。否則,使用受限指數退避並在少量嘗試後停止。除非修正請求、憑證或可用餘額,否則不要重試 400、401 或 402 回應。

大多數 TTS 模型按輸入文字字元收費,而 Gemini TTS 模型則按輸入及輸出 token 收費。一些模型,如 deepgram/flux-tts:free,列為零成本。估算生產成本前請檢查目前的模型頁面或 Models API。

這些控制項涵蓋可靠性、可追蹤性與成本。其餘失敗通常來自將錯誤內容存成音訊或將模型與不支援的聲音或格式結合。

排除常見 OpenRouter TTS 錯誤

為什麼 MP3 內含 JSON?

API 回傳錯誤,程式未檢查狀態碼就直接儲存其內容。請呼叫 raise_for_status() 或檢查狀態碼後再寫入回應。

為什麼音訊檔案是空的或損毀?

空或無法讀取的檔案通常表示請求未返回音訊資料,或回應以錯誤格式儲存。請在儲存前檢查回應大小與 Content-Type。將 audio/mpeg 儲存為 MP3,並以正確播放器設定將 audio/pcm 當作原始 PCM 處理,因為將副檔名改為 .mp3 並不會轉換音訊。

為什麼 OpenRouter 拒絕該聲音?

聲音識別碼因模型而異。請檢查所選模型頁面並傳送其支援的聲音之一。每次更換模型時都要重新確認聲音。

為什麼供應商選項無效?

供應商控制只會作用於對應的供應商,鍵值為供應商 slug。將 MAI-Voice-2 風格的控制放在 provider.options.azure 下。一些供應商會靜默忽略不支援的 speed 值。

在覆蓋回應檢查與供應商特定設定後,其餘問題聚焦於端點、OpenAI SDK 相容性與尋找目前 TTS 模型。

常見問題

OpenRouter 有文字轉語音功能嗎?

有。請向 https://openrouter.ai/api/v1/audio/speech 傳送 POST 請求,包含模型、文字輸入以及該模型支援的聲音。我們以所選模型支援的格式返回原始音訊位元組。

OpenRouter TTS 與 OpenAI SDK 相容嗎?

有。將 SDK 基本 URL 設為 https://openrouter.ai/api/v1 並使用您的 OpenRouter API 金鑰。模型 ID、聲音 ID 以及供應商特定控制仍須與所選模型相符。

如何使用文字轉語音 API?

傳送已驗證的 POST 請求至 https://openrouter.ai/api/v1/audio/speech,包含 model、input 與 voice。設定支援的 response_format,檢查 HTTP 狀態與內容型別,然後將返回的音訊位元組寫入檔案或傳遞給相容播放器。

OpenAI API 中的 TTS 是什麼?

文字轉語音透過 Audio Speech API 將文字輸入轉換為生成的音訊。我們使用相同的請求結構,因此在更改基底 URL 並提供 OpenRouter API 金鑰後,OpenAI SDK 客戶端即可呼叫支援的 OpenRouter TTS 模型。

如何查詢目前的 OpenRouter TTS 模型?

請使用 GET /api/v1/models?output_modalities=speech 或瀏覽 文字轉語音收藏。使用模型頁面確認支援的聲音與目前價格。

端點、認證與回應檢查在這些工作流程中保持一致。模型特定的聲音、格式與控制項是您在每次整合或比較前確認的內容。

使用 OpenRouter 產生語音

在端點、模型、聲音與回應檢查就緒後,您可以使用 cURL、Python、JavaScript 或 OpenAI SDK 產生可播放的音訊檔。請求結構在所有 TTS 模型中保持一致,而每個模型決定可用的聲音、格式與供應商控制項。

建立 API 金鑰 當您準備產生第一個檔案時。瀏覽我們的 文字轉語音模型集合 與 TTS 參考,在比較模型或準備將整合投入生產時。

來源:openrouter blog · openrouter.ai