目錄(34 節)

curl 廣東話 TTS 食譜:由第一個 request 到攞到 mp3

四個指令由零到 mp3;批量、字幕、複製聲線、錯誤處理進階食譜全收錄。

— 港嘢內容團隊約 13 分鐘粵語TTSAPI教學curl開發者
分享:

一句答你: 四個 curl 指令行晒主流程:GET /v1/voices 查聲線 → POST /v1/audio/jobs 提交 → GET /v1/audio/jobs/{id} 輪詢 → curl -o 下載;短句另有同步捷徑一步過。以下全部係可以照抄嘅食譜,根據 2026-10 公開文件。

Key Takeaways

  • 生成係任務式:202 回任務編號 → 輪詢至 completed → 預簽網址下載
  • text 上限 500 字符,超額成個拒絕、唔會截短
  • 同步捷徑 ≤300 字符(圖庫/設計聲線限定),資源未預熱回 503 pool_cold
  • 批量一次 25 個、全有或全無、專業/工作室限定
  • 限流睇 X-RateLimit header,429 照 Retry-After 等
  • 沙盒金鑰每日 20 次生成,開發期唔使嘥正式額度

開爐前準備

三樣嘢:

  1. 金鑰:playground「API 金鑰」頁建立。原始金鑰只顯示一次(系統只存雜湊值),即刻複製。兩個前綴:sk_live_ 正式、sk_test_ 沙盒
  2. Base URL:https://canto-gen.com
  3. 環境變數:
export CANTOGEN_API_KEY="sk_live_你的金鑰"
BASE="https://canto-gen.com"

兩份官方文件擺喺手邊:互動式 API 文件喺 /v1/docs,機讀規格(OpenAPI 3.1、免驗證)喺 /v1/openapi.json。

提示:服務未正式公開時,外部請求有機會喺托管層撞到驗證挑戰頁——嗰個係保護閘,唔係你嘅指令錯。

食譜 1:查聲線目錄

curl -s "$BASE/v1/voices" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY"

回應(節錄):

{
  "voices": [
    {
      "slug": "sum",
      "name": "心妍",
      "gender": "female",
      "age": "adult",
      "styles": [],
      "preview_url": "https://canto-gen.com/api/voice-clip?slug=sum"
    }
  ]
}

重點:slug 先係 API 用嘅聲線識別(中文名只係介面顯示)。目錄係活嘅——用你自己回應入面嘅 slug,唔好照抄示範。每個聲線嘅 gender/age 可以攞嚟做初篩(例如「要成年女聲」),styles 空陣列即係嗰把聲暫時冇演繹風格揀。某把聲支援咩演繹風格,用 GET /v1/voices/{slug}/styles 查;揀聲線嘅詳細準則,前面提到嘅快速上手同完全指南都有講。

食譜 2:提交生成任務

curl -s -X POST "$BASE/v1/audio/jobs" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "voice": "sum",
    "text": "你好,歡迎致電港嘢客服熱線。",
    "response_format": "mp3"
  }'

成功回 202:

{
  "job_id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
  "status": "queued",
  "poll_url": "/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
  "srt_requested": false
}

記住條數:text 1 至 500 字符,超額回 400 text_too_long,成個拒絕、唔會幫你截短。

食譜 3:輪詢至完成

curl -s "$BASE/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY"

狀態生命週期:queued → processing → completed/failed/cancelled。官方建議 2 至 5 秒退避。一個可以照抄嘅小循環:

JOB="$BASE/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b"
while true; do
  S=$(curl -s "$JOB" -H "Authorization: Bearer $CANTOGEN_API_KEY" | jq -r .status)
  echo "status: $S"
  [ "$S" = "completed" ] || [ "$S" = "failed" ] || [ "$S" = "cancelled" ] && break
  sleep 3
done

好消息:輪詢同查目錄呢啲讀取接口唔計限流,放心 poll。

食譜 4:下載音頻

completed 嗰下回應會帶 audio_url(預簽,下載唔使再帶金鑰):

curl -sL -o speech.mp3 "$AUDIO_URL"

時效要記住:已入音頻庫嘅網址有效 1 小時;由生成端直接出、未入庫嘅有效 7 日。完成就即刻載;過咗期唔使重生成,再 poll 一次任務攞條新網址就得。排隊/處理中/失敗/取消嘅任務,回應係冇 audio_url 嘅。腳本入面最好將「下載成功」同「取得網址」分開驗證——網址攞到唔等於檔案落到手,中間仲有網絡同磁碟兩關。

捷徑食譜:同步短句

≤300 字符、圖庫或設計聲線,可以一步過攞音頻(回應仲有 X-Audio-Duration 同 X-Credits-Charged header):

curl -s -X POST "$BASE/v1/audio/speech" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"voice": "sum", "text": "多謝致電,再見。"}' \
  --output speech.mp3

防禦位:同步專用資源未預熱時,呢個接口會 fail closed 回 503 pool_cold(附 hint 提你轉任務式),唔會靜靜幫你轉。咁樣設計係好事——你永遠知道音頻係行咗邊條路出嚟,唔會有「以為行同步、其實行咗任務式」嘅模糊地帶。代價係你嘅腳本要寫定後備:

CODE=$(curl -s -o speech.mp3 -w "%{http_code}" -X POST "$BASE/v1/audio/speech" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" -H "Content-Type: application/json" \
  -d '{"voice": "sum", "text": "你好"}')
[ "$CODE" = "503" ] && echo "改行任務式流程"

進階食譜

字幕:SRT

提交時加 "srt": true,任務完成後輪詢回應會帶 srt 內容(SRT 格式字幕全文)。留意開字幕會有附加計費(帳單字符多過正文),金鑰月度上限就照正文長度計。

設計聲線:design

用性別+年齡描述一把新聲(兩項都要有,缺任一項回 400):

curl -s -X POST "$BASE/v1/audio/jobs" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "design": { "gender": "female", "age": "young" },
    "text": "今日天氣幾好,一齊去行山啦。",
    "emotion": "happy",
    "srt": true
  }'

聲音複製:clone

要金鑰帶 tts:clone 權限。參考音頻用 base64 或 data URL(wav/mp3/webm/m4a/ogg,上限 20 MB),逐字稿 prompt_text 必填(缺咗回 400 clone_prompt_text_required);乾淨 10 至 30 秒樣本效果最好:

B64=$(base64 -w0 sample.wav)
curl -s -X POST "$BASE/v1/audio/jobs" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"clone\": {\"reference_audio\": \"data:audio/wav;base64,$B64\", \"prompt_text\": \"呢段係參考音訊嘅逐字稿。\"}, \"text\": \"用我把聲講呢句嘢。\"}"

設計同複製出嚟嘅聲線係單次請求性質,唔會存底——要長期用同一把聲,用圖庫 slug。

批量:items

一次過交最多 25 個任務:

{ "items": [ { "voice": "sum", "text": "第一句。" }, { "voice": "sum", "text": "第二句。" } ] }

三條規矩:專業/工作室方案限定(其他方案交批量會被拒,零提交零扣費);驗證全有或全無(任何一項無效,成批 400 invalid_items 拒收);超過 25 項回 400 too_many_items。202 回應逐項回報任務編號。實務位:批量係「提交」嘅批,唔係「輪詢」嘅批——每項仍然係獨立任務,各自行 queued → processing → completed,輪詢要逐項跟。完整批量工作流(分批策略、進度管理)睇批量生成工作流。

撞到錯誤點讀

錯誤回應一律有穩定 error 碼——係你腳本可以程式化判斷嘅依據,唔係俾人睇嘅裝飾:

{ "error": "text_too_long", "message": "text exceeds 500 characters." }

高頻幾個:400 參數類(文字超長、格式唔支援、emotion 值唔合法——改 payload,唔好重試);401 金鑰無效/過期/被撤銷;403 額度到頂(monthly_cap_reached,回應有 used)或者缺權限(複製要 tts:clone);429 限流;5xx 暫時性問題。完整對照表逐個碼嘅對策,睇錯誤碼大全。

限流 header 點讀

提交接口嘅 202 同 429 回應帶 X-RateLimit-Limit/-Remaining/-Reset;撞限流回 429 附 Retry-After 秒數:

HTTP/1.1 429 Too Many Requests
Retry-After: 42
X-RateLimit-Remaining: 0

照 Retry-After 等就啱。

音頻格式同後製少少門道

curl 攞到嘅 mp3/wav 落到手之後:

  • mp3:通用、細檔,網頁播放、通訊軟件傳送都方便
  • wav:無損,要再後製(混音、剪接、加背景樂)先用佢,避免二次壓縮損質
  • 播放平台嘅要求話事:電話 IVR 常有取樣率同格式要求,以你自己平台嘅規格做最後一轉
  • 响度統一:成批音頻要音量一致,後製工具做一次响度正規化——尤其播報類,一忽大聲一忽細聲係最常見嘅投訴位

生成端出乾淨原料,後製做最后一里,分工清楚就唔會互相補鑊。

開發期:用沙盒金鑰

免費/入門方案可以開 sk_test_ 沙盒金鑰:每日 20 次生成(按帳戶計,跨金鑰共享),只計提交、輪詢下載唔計。試腳本、試錯誤處理,用沙盒唔使肉痛。升上專業方案之後,現有金鑰即時自動變全速,唔使重新接過。金鑰治理(權限範圍、限流、月度上限、過期時間、撤換流程)另文有詳細做法(API 金鑰管理與驗證)。整體 API 起步流程睇粵語 TTS API 快速上手;由零認識港嘢語音生成,睇廣東話 TTS 完全指南。

揀模式:同步定任務式?

兩條路點揀,一張表睇晒:

同步捷徑任務式
字符上限300500
聲線圖庫/設計圖庫/設計/複製
SRT 字幕支援唔到支援
回應方式直接回音頻檔202+輪詢
資源未預熱503 fail closed照常排隊
適合場景短句即用長文、字幕、複製、批量

簡單講:一句兩句即場用,同步;有字幕、要複製、或者成批做,任務式。兩條路同樣按字符計費,唔使糾結成本差異——揀邏輯純粹係功能同流程。

常用參數速查

參數可用值備註
voice圖庫 slug同 design/clone 三選一,多揀回 400
designgender+age兩項都要有
clonereference_audio+prompt_text要 tts:clone 權限
emotion9 個值happy/sad/angry/fearful/disgusted/surprised/neutral/excited/gentle
style自由文字演繹風格提示
languageyue/zh/en預設 yue
response_formatmp3/wav預設 mp3
srttrue/false行任務式軌
text1–500 字符超額成個拒收

仲有一個舊知識要更新:早年文件有 speed/pitch/volume 三個參數,而家已經退役——接口照收但完全冇效果,新腳本唔好再送呢三個值。

錯誤碼速查(高頻十個)

HTTPerror 碼一句講晒
400text_too_long文字過 500,拆句
400voice_mode_conflict聲線模式多揀咗
400invalid_items批量有項目無效,成批拒
400clone_prompt_text_required複製缺逐字稿
401invalid_or_expired_token金鑰無效/過期/被撤
403monthly_cap_reached金鑰月度上限到
403batch_requires_pro批量要專業/工作室方案
429rate_limit_exceeded每分鐘限流,睇 Retry-After
429in_flight_limit_reached在途任務滿額
503pool_cold同步資源未預熱,轉任務式

其餘碼同每個嘅詳細對策,睇返上面「撞到錯誤點讀」一節嘅專文連結。

批量腳本:由文字檔到一次提交

台詞放喺一個 JSON array(每項一句),拼 payload 一次過交:

jq -n --slurpfile texts texts.json \
  '{items: [ $texts[] | {voice: "sum", text: .} ]}' > payload.json

curl -s -X POST "$BASE/v1/audio/jobs" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d @payload.json

提交前兩個習慣:逐項自查 500 字符上限(批量係全有或全無,一項超額成批報廢);202 回應逐項嘅任務編號即刻入你自己嘅任務表,輪詢先有得跟。另外記住批量係「提交」嘅批、唔係「完成」嘅批——25 項唔會同時完成,下載觸發要逐項認,唔好假設成批會一齊搞好。

SRT 兩個貼士

  • 字幕內容喺 completed 嘅輪詢回應度,同音頻網址並排出現;冇開 srt 嘅任務,回應唔會有呢嚿嘢
  • 開字幕有附加計費(帳單字符多過正文),估算成本嗰陣計埋呢筆;金鑰月度上限就照正文長度計,兩本帳唔同
  • 字幕係驗稿神器:逐句對照字幕同文稿,讀漏、重複、錯序一睇就知——驗收長音頻,睇字幕快過聽音頻

聲線目錄點管理

目錄唔使 hard-code:開波拉一次 /v1/voices 存入你自己嘅設定,定期(例如每星期)重拉一次同步新聲線。slug 係穩定識別,唔會飄,但目錄會添食——定期同步先唔會錯過新把聲。

十個常見新手錯誤

食譜睇得多,都係呢十嘢最多人中招:

  1. 金鑰寫死喺腳本——寫入環境變數或者設定檔,仲要入 .gitignore;原始金鑰得一次展示機會,存好佢
  2. text 冇 trim 就交——首尾空白位都計字符,長文場景隨時因此而超限
  3. 用 curl 預設嘅 form-encoded——記得 Content-Type: application/json,唔係嘅話參數全部讀唔到
  4. poll 冇終態判斷——failed/cancelled 都係終態,唔識跳出就 poll 到天荒地老
  5. audio_url 當永久連結——1 小時/7 日時效,完成即刻下載
  6. 撞 400 就重試——參數錯重試幾多次都係 400,改 payload 先至係路
  7. 批量交完唔記任務編號——202 逐項嘅編號即刻入表,否則冇得輪詢
  8. 同步接口冇後備——503 pool_cold 係設計行為,任務式後備一定寫定
  9. 多重試冇上限——冇 MAX_RETRIES 嘅 loop,撞 5xx 就係無限燒
  10. 日誌冇記 error 碼——第日排查,得一個「失敗咗」係冇用嘅

將呢十條印出嚟貼喺 moni 旁邊,可以慳返好多个鐘 debug。

將呢十條印出嚟貼喺螢幕旁邊,可以慳返好多個鐘 debug。

多把金鑰:環境同用途分開

認真少少嘅項目,金鑰唔止一把:

  • 開發用一把、正式用一把——出事唔會互相拖累
  • 環境變數分名:CANTOGEN_API_KEY_DEV/CANTOGEN_API_KEY_PROD,腳本按環境讀
  • 可以設月度上限:開金鑰時可以為每把 key 設每月字符上限,開發把 key 設低啲,意外都燒唔起正式額度
  • 撤換有紀律:金鑰懷疑外洩,即刻撤舊開新——撤換係金鑰管理嘅日常,唔係事故

金鑰治理嘅完整做法(權限範圍、過期時間、撤換流程)另文有詳細講。

Debug 心法:由回應學嘢

API 嘅錯誤回應唔係 obstacle,係線索。養成三個習慣:

  • 完整讀個回應先:HTTP 碼、error 碼、message 三層資訊,好多時 message 直接話你知邊個參數出事
  • 縮細法排查:唔知邊個參數出事,就將 payload 縮到最細(得 voice+text),行得通再逐個參數加返——兩分鐘捉到元兇
  • 對照文件讀:error 碼一律對返官方錯誤表理解,唔好靠估——每個碼都係文件化嘅,冇神秘空間

debug 嘅速度差別,通常唔係技術高低,係有冇讀回應嘅習慣。

一個完整示例:由零到一段廣告旁白

將成篇文章收攏:假設要為一段 200 字符嘅門市廣告旁白出 mp3,完整腳本:

#!/usr/bin/env bash
set -e
export CANTOGEN_API_KEY="sk_live_..."     ## 1. 金鑰入環境變數
BASE="https://canto-gen.com"

## 2. 提交(任務式,文字預先執好:口語、全形標點、500字符內)
RESP=$(curl -s -X POST "$BASE/v1/audio/jobs" \
  -H "Authorization: Bearer $CANTOGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"voice": "sum", "text": "今個周末,嚟銅鑼灣分店……", "response_format": "mp3"}')

JOB_ID=$(echo "$RESP" | jq -r .job_id)    ## 3. 任務編號即刻入袋
echo "job: $JOB_ID"

## 4. 輪詢至終態(2–5秒退避)
while true; do
  S=$(curl -s "$BASE/v1/audio/jobs/$JOB_ID" \
      -H "Authorization: Bearer $CANTOGEN_API_KEY")
  ST=$(echo "$S" | jq -r .status)
  [ "$ST" = "completed" -o "$ST" = "failed" -o "$ST" = "cancelled" ] && break
  sleep 3
done

## 5. 完成就即刻下載(預簽網址有時效)
[ "$ST" = "completed" ] && \
  curl -sL -o ad-2026.mp3 "$(echo "$S" | jq -r .audio_url)" && echo "done"

呢個腳本已經包住晒核心衛生習慣:金鑰入環境變數、任務編號入袋、終態判斷、完成即下載。你嘅正式系統,就係喺呢個骨架上長出重試、日誌同批量。

常見問題 FAQ

有冇辦法唔使輪詢?

目前接口設計係任務式,輪詢係標準做法;好在讀取接口唔計限流,2 至 5 秒退避嘅輪詢成本好低。需要「完成即通知」嘅架構,可以喺你自己系統加一層輪詢 worker 轉回調,另文有專門講。順帶一提,輪詢仲有一個好處:你完全掌控節奏同並發,debug 嗰陣每一步都睇得到——對初接入嘅團隊嚟講,透明度比「自動魔術」更值錢。

mp3 定 wav?

response_format 兩個值:mp3(預設,通用)同 wav(無損,後製方便)。電話 IVR 多數要 wav 特定取樣率,用你自己平台嘅規格話事。揀唔到就用 mp3——兼容性最廣,之後要轉格式,任何音頻工具都做得到。

提交嗰下要帶齊咩參數?

最細要求係 voice+text 兩樣;response_format 唔帶就預設 mp3。emotion、style、language、srt 全部 optional,按需加。建議腳本由最細 payload 開始,行通咗先逐個加——一次過帶十個參數,出事唔知邊個係元兇。

音頻可以直接串流播放嗎?

接口回嘅係完整音頻檔(唔係串流軌),播放端攞到檔案先播。短句場景呢個模式冇問題(檔細、載得快);長內容想「邊載邊播」,靠播放器自己嘅漸進式播放就得——mp3 本身支援。真正嘅「生成中途串流」係另一種接口形態,目前任務式流程唔涉及。

點知我把 key 係唔係沙盒?

睇前綴:sk_test_ 開頭係沙盒、sk_live_ 開頭係正式。唔肯定嗰陣直接打一次 /v1/voices——沙盒都行得;再交一單生成,撞 429 嘅話睇下係咪每日 20 次嘅帳。分清楚兩種 key 嘅最簡單方法:命名同環境變數由第一步就分開。

提交成功但唔記得任務編號點算?

任務編號要自己保存——而家冇「按內容搵任務」嘅接口。腳本好習慣:提交成功即刻將編號寫入你自己嘅任務記錄,連你嘅業務參考號一齊存。

批量交咗之後點追蹤進度?

202 回應逐項有輪詢地址,逐項 poll 就得;或者喺你系統入面起一個任務表,記每項狀態,聚合顯示。

[!CTA]

開住 terminal 試第一個 request

免費開戶即有金鑰同每月 5,000 字符,四個指令由零到 mp3。

相關文章