รับไทม์สแตมป์ระดับคำ
ไทม์สแตมป์คือช่วงเวลาระดับคำ ประโยค หรือช่วงพูด ที่ส่งกลับมาพร้อมไฟล์เสียง สำหรับคำบรรยายและ UI อ่านตามเสียง ออปชันเดียวเปลี่ยนทั้งรูปแบบการตอบกลับและอัตราค่าบริการ
ไทม์สแตมป์คือช่วงเวลาระดับคำ ประโยค หรือช่วงพูด ที่ส่งกลับมาพร้อมไฟล์เสียง ตั้งค่า timestamps ใน POST /v1/tts เพื่อรับข้อมูลนี้ การตอบกลับจะมีทั้งเสียงและช่วงเวลา (span) แต่ละช่วงบอกข้อความ เวลาเริ่ม และเวลาจบเป็นวินาที คำขอที่มีไทม์สแตมป์คิด 1.25 เท่าของอัตราตามตัวอักษรของโมเดล ปัดเศษขึ้นถึงหนึ่งในร้อยของเครดิต ขั้นต่ำ 0.1 เครดิตต่อคำขอ
curl -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",
"timestamps": "word"
}' \
-o response.json
jq -r .audio response.json | base64 -d > speech.mp3
jq .timing.spans response.jsonimport { writeFile } from "node:fs/promises";
const 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",
timestamps: "word",
}),
});
if (!response.ok) throw new Error(`TTS failed: ${response.status}`);
const { audio, timing } = await response.json();
await writeFile("speech.mp3", Buffer.from(audio, "base64"));
for (const span of timing.spans) {
console.log(`${span.start.toFixed(2)}s ${span.text}`);
}import base64
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",
"timestamps": "word",
},
)
response.raise_for_status()
data = response.json()
with open("speech.mp3", "wb") as f:
f.write(base64.b64decode(data["audio"]))
for span in data["timing"]["spans"]:
print(f"{span['start']:.2f}s {span['text']}")เลือกระดับการแบ่งช่วง#
ค่าของ timestamps กำหนดวิธีแบ่งช่วงเสียง ทุกช่วงมี text start และ end เป็นวินาที ช่วงเวลาครอบคลุมข้อความที่ถูกพูด และแท็กอารมณ์ไม่มีช่วงเวลาของตัวเอง
| ค่า | ช่วงที่ได้ |
|---|---|
| word | หนึ่งช่วงต่อหนึ่งคำพูด ภาษาไทยโมเดลแบ่งคำให้เอง ข้อความไม่ต้องเว้นวรรค |
| sentence | หนึ่งช่วงต่อหนึ่งประโยค |
| utterance | หนึ่งช่วงต่อการพูดต่อเนื่องระหว่างจังหวะหยุด ช่วงพูดหนึ่งอาจครอบคลุมหลายประโยคที่อ่านรวดเดียว หรือเป็นบางส่วนของประโยคยาว |
รูปแบบการตอบกลับ#
เมื่อรับแบบไฟล์เต็ม การตอบกลับเป็น application/json แทนเสียงไบนารี: audio คือไฟล์เสียงทั้งไฟล์เข้ารหัส base64 และ timing.spans คือช่วงเวลาทั้งหมดตามระดับที่ขอ ถอดรหัส audio แล้วได้ไบต์เดียวกับคำขอที่ไม่มีไทม์สแตมป์ทุกประการ เฮดเดอร์ตามปกติรวมทั้ง x-credits-charged ยังครบเหมือนเดิม
{
"audio": "SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjYy...",
"timing": {
"granularity": "word",
"spans": [
{
"text": "สวัสดี",
"start": 0,
"end": 0.51
},
{
"text": "ครับ",
"start": 0.51,
"end": 0.85
},
{
"text": "ยินดี",
"start": 0.85,
"end": 1.27
},
{
"text": "ต้อนรับ",
"start": 1.27,
"end": 1.87
},
{
"text": "สู่",
"start": 1.87,
"end": 2.12
},
{
"text": "Paxa",
"start": 2.12,
"end": 2.46
},
{
"text": "Labs",
"start": 2.46,
"end": 2.8
}
]
}
}สตรีมเสียงพร้อมไทม์สแตมป์#
เมื่อ stream: true การตอบกลับเป็น application/x-ndjson: หนึ่งอีเวนต์ JSON ต่อบรรทัด แต่ละบรรทัดมีช่วงเสียง base64 กับ span ที่เสียงช่วงนั้นพูดจบ ปิดท้ายด้วยอีเวนต์ done ที่บอกจำนวน span ทั้งหมด เพื่อให้ฝั่งรับตรวจได้ว่าเก็บครบทุกตัว ส่วนตัว span เองส่งเพียงครั้งเดียวในบรรทัด chunk หากสตรีมจบโดยไม่มี done ให้ถือว่าคำขอล้มเหลว ระบบคืนเครดิตให้อัตโนมัติ กติกาเดียวกับการสตรีมเสียง
{"type":"chunk","audio":"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjYy...","spans":[{"text":"สวัสดี","start":0,"end":0.51},{"text":"ครับ","start":0.51,"end":0.85},{"text":"ยินดี","start":0.85,"end":1.27}]}
{"type":"chunk","audio":"SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjYy...","spans":[{"text":"ต้อนรับ","start":1.27,"end":1.87},{"text":"สู่","start":1.87,"end":2.12},{"text":"Paxa","start":2.12,"end":2.46},{"text":"Labs","start":2.46,"end":2.8}]}
{"type":"done","granularity":"word","span_count":7}ค่าบริการ#
ค่าบริการส่วนเพิ่มใช้เฉพาะเมื่อตั้ง timestamps เท่านั้น: คำขอเดิมคิด 1.25 เท่าของราคาแบบไม่มีไทม์สแตมป์ เช่นคำขอ 36 ตัวอักษรคิด 0.45 เครดิตเทียบกับ 0.36 เครดิต ดูอัตราตามตัวอักษรของแต่ละโมเดลได้ที่ GET /v1/models ส่วนการปัดเศษและขั้นต่ำ 0.1 เครดิตเหมือนในเครดิตและค่าบริการทุกประการ ลองกับข้อความของคุณเองได้ในเพลย์กราวด์ โมเดลเบื้องหลังเสียงพูดแบบจับเวลามีหน้าของตัวเองที่แปลงข้อความเป็นเสียง
หมายเหตุ
เอนด์พอยต์แบบ OpenAI ละเว้น timestamps เพราะรูปแบบคำขอของ OpenAI ไม่มีฟิลด์นี้ ข้อมูลเวลายังใช้ได้บนการเชื่อมต่อสดทุกการเชื่อมต่อ ในราคาเดียวกัน