廣告位招商中 歡迎洽談

使用 Listnr 語音合成 API 實現音訊串流傳輸與自訂語音參數配置

365Finds Editorial
已收錄 11,430 篇 Wiki 文章

讓你的 AI 用上 365 Wiki

複製下方的提示詞,貼給你常用的 AI,然後直接提問。

下載完整版 Skill

先用提示詞體驗;經常使用時,安裝完整版 365Wiki Skill,以後無需重複複製。沒有常用 AI?Gemini、Microsoft Copilot 等網頁版也可以。

365Wiki Skill

在現代 Web 應用程式中整合即時文字轉語音(TTS)技術,工程師面臨的核心挑戰在於兼顧首包低延遲、聲音真實感與 API 憑證的安全性。Listnr 提供了雙軌 API 架構:一方面透過標準 V1 REST 介面整合微軟 Azure、Google Cloud、AWS Polly 與 IBM Watson 的跨平台音色庫;另一方面針對 Ultra Premium 與聲音複製(Cloned Voices)提供具備低延遲特性的 V2 串流端點 /stream-voice。

為了在前端應用中實現流暢且安全的語音播放,最佳實踐是由後端建立輕量代理轉發層,附加授權金鑰呼叫 Listnr 串流介面,調整情感與語速參數,並將二進位音訊資料區塊直接串流管線化(pipe)推送至瀏覽器。

sequenceDiagram
    autonumber
    actor User as 瀏覽器前端
    participant Server as 應用後端代理
    participant Listnr as Listnr V2 串流 API
    
    User->>Server: POST /api/tts (文字, voiceId, 語音設定)
    Note over Server: 安全附加 x-listnr-token
    Server->>Listnr: POST /api/v2/stream-voice
    Listnr-->>Server: 分塊二進位音訊串流 (WAV / MP3)
    Server-->>User: 管線化音訊串流 (Transfer-Encoding: chunked)
    Note over User: Web Audio API / HTML5 Audio 即時緩衝播放

1. 身分驗證機制與架構設計原則

Web 前端絕對不能直接暴露含有生產金鑰的 Listnr 呼叫。Listnr 透過專屬的請求標頭(x-listnr-token)驗證身分,該金鑰直接連結至開發者帳戶的字數額度與扣費方案。若在客戶端程式碼中洩漏金鑰,極易導致配額被盜用。

憑證防護與後端代理架構

業界標準的整合模式是在瀏覽器與 Listnr 伺服器之間設置轉發層(例如 Next.js API Routes、Express、Fastify 或 FastAPI)。

介面組件端點路徑核心用途安全性與呼叫要求
V2 串流音訊介面https://cloning.listnr.tech/api/v2/stream-voiceUltra Premium 與複製聲音的超低延遲二進位分塊串流僅限伺服器端呼叫;必須帶入 x-listnr-token
V2 聲音清單介面https://cloning.listnr.tech/api/v2/available-voices查詢可用音色模型、預設設定檔與自建複製聲音清單伺服器記憶體快取;提供前端選單存取
V1 多廠商 RESThttps://bff.listnr.tech/api/tts/v1/convert-text批次產生 Azure、Google、AWS 等多供應商語音適用於批次轉換;支援標準 SSML 根標籤

2. 探索聲音模型:獲取 Voice ID

在發送合成請求之前,應用程式必須先取得有效的語音模型識別碼(voice_id)。系統可在後端啟動時向語音查詢端點擷取列表,或將其快取在 Redis 等快取儲存中。

# 查詢帳戶可用的預設與複製聲音清單
curl -X GET "https://cloning.listnr.tech/api/v2/available-voices" \
  -H "x-listnr-token: YOUR_LISTNR_API_KEY" \
  -H "Accept: application/json"

回應結果會包含一組具備專屬代碼(如 21m00Tcm4TlvDq8ikWAM)的聲音物件。前端將使用者選定的 ID 傳遞給後端,即可精準套用目標音質。


3. 音訊串流合成與自訂參數調優

Listnr V2 串流端點接收 JSON 格式的請求主體,包含待朗讀文字、聲音模型 ID 以及負責微調聲線質感的 settings 物件。

{
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "text": "系統警告:資料庫複本同步延遲。<break time=\"0.4s\"/><break strength=\"strong\"/>即將啟動備援移轉程序。",
  "settings": {
    "stability": 0.71,
    "similarity_boost": 0.50,
    "style": 0.05,
    "use_speaker_boost": false
  }
}

關鍵參數微調指南

深入理解參數對聲學特性的影響,有助於在聲音表現力與穩定性間取得平衡:

SSML 停頓與節奏標籤

在 V2 /stream-voice 串流中,開發者無需包裝完整的 <speak> 標籤,即可在文字中直接穿插 SSML 停頓控制標籤:


4. Web 應用全端實作範例

以下範例呈現了適用於生產環境的完整串流管線:包含 Node.js/Express 後端代理伺服器,以及前端採用 Fetch API 進行音訊串流接收與播放的範例。

後端串流代理模組(server.js)

import express from 'express';
import fetch from 'node-fetch';

const app = express();
app.use(express.json());

const LISTNR_API_KEY = process.env.LISTNR_API_KEY;
const STREAM_URL = 'https://cloning.listnr.tech/api/v2/stream-voice';

app.post('/api/tts/stream', async (req, res) => {
  try {
    const { text, voiceId, settings } = req.body;

    if (!text || !voiceId) {
      return res.status(400).json({ error: '缺少 text 或 voiceId 參數。' });
    }

    const payload = {
      voice_id: voiceId,
      text: text,
      settings: {
        stability: settings?.stability ?? 0.71,
        similarity_boost: settings?.similarity_boost ?? 0.50,
        style: settings?.style ?? 0.0,
        use_speaker_boost: settings?.use_speaker_boost ?? false
      }
    };

    const upstreamResponse = await fetch(STREAM_URL, {
      method: 'POST',
      headers: {
        'x-listnr-token': LISTNR_API_KEY,
        'Content-Type': 'application/json',
        'Accept': '*/*'
      },
      body: JSON.stringify(payload)
    });

    if (!upstreamResponse.ok) {
      const errorText = await upstreamResponse.text();
      return res.status(upstreamResponse.status).json({
        error: `Listnr API 回應異常: ${upstreamResponse.statusText}`,
        details: errorText
      });
    }

    // 設定串流標頭,支援分塊資料推送
    res.setHeader('Content-Type', 'audio/wav');
    res.setHeader('Transfer-Encoding', 'chunked');

    // 將上游音訊串流直接導入客戶端回應通道
    upstreamResponse.body.pipe(res);
  } catch (err) {
    console.error('TTS 串流傳輸錯誤:', err);
    res.status(500).json({ error: '伺服器端代理發生未預期異常。' });
  }
});

app.listen(3000, () => console.log('語音代理伺服器已在連接埠 3000 啟動'));

前端串流擷取與播放(client.js)

/**
 * 請求後端音訊串流並在資料抵達時即刻播放
 */
async function streamAndPlayAudio(text, voiceId) {
  const response = await fetch('/api/tts/stream', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      text: text,
      voiceId: voiceId,
      settings: {
        stability: 0.65,
        similarity_boost: 0.60,
        style: 0.0
      }
    })
  });

  if (!response.ok) {
    throw new Error(`音訊請求失敗,狀態碼: ${response.status}`);
  }

  // 將二進位分塊資料轉換為 Blob 物件並由 HTML5 Audio 播放
  const audioBlob = await response.blob();
  const audioUrl = URL.createObjectURL(audioBlob);
  const audio = new Audio(audioUrl);
  
  audio.onended = () => URL.revokeObjectURL(audioUrl);
  await audio.play();
}

5. 工程架構考量與權衡取捨

將 Listnr TTS 導入生產級系統時,架構師應評估以下核心要點:

  1. V1 REST 與 V2 串流的架構取捨:若系統依賴微軟 Azure 或 Google 雲端既有的傳統音色,或需要精確的單字級時間戳記(Word Timestamps)進行歌詞與字幕聯動,應選用 V1 介面;若業務核心為擬真人對話、極致低延遲及自訂克隆聲線,則應全面採用 V2 串流。
  2. 字數額度防護與請求防抖(Debounce):Listnr 依據合成字元數量扣除點數。在動態對話或輸入欄位觸發語音的情境下,前端必須加上防抖保護,並利用 AbortController 提早中斷先前未完成的網路請求。
  3. 靜態語音資產的邊緣快取:對於固定問候語、系統錯誤代碼與標準教學引導,應在伺服器端快取至 S3 等物件儲存服務並透過 CDN 分發,僅將高成本的即時 API 串流保留給動態生成內容。

參考資料