สตรีมเสียงระหว่างการสังเคราะห์
การสตรีมส่งเสียงเป็นช่วง ๆ ระหว่างที่การสังเคราะห์ยังทำงาน ลดเวลารอเสียงแรก ตั้ง stream: true หรือใช้เอนด์พอยต์แบบ OpenAI ที่สตรีมเป็นค่าเริ่มต้น
การสตรีมคือการส่งเสียงเป็นช่วง ๆ ระหว่างที่การสังเคราะห์ยังทำงานอยู่ ตั้ง stream: true ใน POST /v1/tts แล้วไบต์แรกจะมาถึงระหว่างที่ส่วนที่เหลือยังสังเคราะห์อยู่ ช่วยลดเวลารอเสียงแรกสำหรับงานเรียลไทม์อย่าง voice agent หรือการบรรยายสด ส่วนเอนด์พอยต์แบบ OpenAI สตรีมเป็นค่าเริ่มต้นอยู่แล้ว การสตรีมในหน้านี้คือการส่งทางเดียวของคำขอเดียว หากต้องการการเชื่อมต่อสองทางที่ทยอยส่งข้อความได้ ดูที่สตรีมสดสองทาง
curl -N -X POST https://api.paxalabs.com/v1/tts \
-H "Authorization: Bearer $PAXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs", "voice": "khanomkrok", "model": "paxa-tts-flash-v2", "stream": true}' \
--output speech.mp3const response = await fetch("https://api.paxalabs.com/v1/tts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
voice: "khanomkrok",
model: "paxa-tts-flash-v2",
stream: true,
}),
});
if (!response.ok || !response.body) {
throw new Error(`TTS failed: ${response.status}`);
}
// Chunks arrive while synthesis is still running.
for await (const chunk of response.body) {
player.feed(chunk);
}import os
import requests
response = requests.post(
"https://api.paxalabs.com/v1/tts",
headers={"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"},
json={"text": "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs", "voice": "khanomkrok", "model": "paxa-tts-flash-v2", "stream": True},
stream=True,
)
response.raise_for_status()
with open("speech.mp3", "wb") as f:
for chunk in response.iter_content(chunk_size=None):
f.write(chunk)การส่งแบบไฟล์เต็มและแบบสตรีม#
ไฟล์เต็ม (stream: false) | สตรีม (stream: true) | |
|---|---|---|
| การส่ง | เนื้อหาครบพร้อม content-length | ส่งทีละช่วงตามการสังเคราะห์ |
| ไบต์แรก | หลังสังเคราะห์เสร็จทั้งหมด | ทันทีที่ช่วงแรกพร้อม |
| ความล้มเหลวหลังเริ่มส่ง | ตอบ 502 พร้อมรายละเอียดครบ | สตรีมถูกตัดกลางทาง ไม่มีข้อความปิดท้าย |
อ่านสตรีม#
ส่งช่วงเสียงเข้าเครื่องเล่นหรือซ็อกเก็ตทันทีที่มาถึง ค่อยรวมเนื้อหาทั้งหมดเฉพาะตอนเขียนไฟล์ ค่าบริการคิดก่อนการสังเคราะห์และ x-credits-charged เป็นเฮดเดอร์ของการตอบกลับ จึงรู้ต้นทุนที่แน่นอนตั้งแต่ไบต์แรกแม้อยู่กลางสตรีม
เมื่อตั้ง timestamps การตอบกลับแบบสตรีมจะเปลี่ยนจากช่วง MP3 ดิบเป็นอีเวนต์ NDJSON ที่ส่งเสียงและข้อมูลเวลามาด้วยกัน ดูรูปแบบอีเวนต์ได้ในข้อมูลอ้างอิง
จัดการข้อผิดพลาด#
การตอบกลับจะยืนยันสถานะเมื่อส่งช่วงแรกออกไปแล้ว หากล้มเหลวก่อนไบต์แรก ระบบตอบ 502 provider_error และคืนเครดิตให้ หากล้มเหลวกลางสตรีม การเชื่อมต่อจะจบก่อนกำหนด ให้ถือว่าสตรีมที่ปิดผิดปกติคือคำขอที่ล้มเหลว ระบบคืนเครดิตให้โดยอัตโนมัติเช่นกัน
หากคุณยกเลิกคำขอเอง ระบบยังคิดเครดิตตามปกติ เพราะเสียงกำลังถูกส่งตามที่จ่ายไว้ ถ้างานของคุณต้องการผลแบบได้ครบหรือไม่ได้เลย เช่นบันทึกไฟล์ไว้ใช้ภายหลัง แนะนำให้ใช้แบบไฟล์เต็ม
หมายเหตุ
ใช้สตรีมคู่กับ Idempotency-Key หากการเชื่อมต่อของคุณหลุด การส่งซ้ำด้วยคีย์เดิมจะได้รับผลลัพธ์อีกครั้งโดยไม่ถูกคิดเครดิตซ้ำ แต่หากการสังเคราะห์เองล้มเหลวและคืนเครดิตแล้ว การส่งซ้ำจะตอบ 409 idempotency_refunded และต้องใช้คีย์ใหม่