Thai speech to text for video captions
Caption recorded Thai video from its own audio. Word timestamps mark where each cue starts and ends in a script that has no spaces to break on.
What the transcript says
A lecture on interest
spokenถ้าฝากเงิน หนึ่งแสนบาท ที่ดอกเบี้ย สองจุดห้าเปอร์เซ็นต์ ต่อปี ครบปีได้ดอกเบี้ย สองพันห้าร้อยบาท
writtenถ้าฝากเงิน 100,000 บาท ที่ดอกเบี้ย 2.5% ต่อปี ครบปีได้ดอกเบี้ย 2,500 บาท
The written convention fits the figures on one caption line. The spoken one matches the lecturer word for word.
An interview answer
spokenเราเริ่มจาก ทีมสามคน ตอนนี้มี สี่สิบคน แล้ว ส่วนใหญ่เป็น engineer ค่ะ
writtenเราเริ่มจาก ทีม 3 คน ตอนนี้มี 40 คน แล้ว ส่วนใหญ่เป็น engineer ค่ะ
The English word stays English in the caption, timed like every other word.
A product walkthrough
spokenกดปุ่มด้านล่างขวา แล้วเลือกแผน สามร้อยเก้าสิบเก้าบาท ต่อเดือน
writtenกดปุ่มด้านล่างขวา แล้วเลือกแผน 399 บาท ต่อเดือน
A price on screen should read as a price. The written convention writes it that way without an edit pass.
Every transcript pair on this page is an authored illustration of what the convention option changes, re-checked against live output before publish. The Speech-to-Text page carries the model's own witnessed transcripts of a real recording, with the capture date.
How it fits a video workflow
A caption is a transcript cut into cues, each on screen for the seconds its words are spoken. In English the cut falls between words. Thai writes without spaces. A caption tool has nothing to cut on unless it knows where each word begins. Word timestamps are that knowledge. Send the audio track of a lecture, an interview, or a product video and every word comes back with its start and end. Group the words into lines of a comfortable length, and the cue times are already there. The spoken convention keeps the caption faithful to the voice. The written one keeps figures readable on a phone screen.
- Extract the audio trackAny container the model reads works: M4A or AAC from the video, or a WAV or MP3 export, up to 60 minutes a request.
- Transcribe with word timestampsSet timestamps to word. Pick the spoken convention for captions that follow the voice, the written one for figures a viewer reads.
- Cut cues and write the fileGroup the spans into lines by your house style, close a cue on a long pause, and serialize as SRT or WebVTT.
How a caption is cut
- 1 word
- One span
- Every word arrives with a start and an end in seconds. In a script with no spaces, the spans are the word boundaries.
- ≈ 32
- Characters a line
- Group consecutive words until a line is full or a pause opens. The cue starts at the first word's start and ends at the last word's end.
- Pauses
- A gap between one word's end and the next word's start is a pause. A long one closes the cue early. A caption never hangs over silence.
- Formats
- SRT and WebVTT are a few lines of code over the cue list. The transcript stays the source when a caption is corrected by hand.
The line length is a house style, set in your code. The timestamps are the model's.
What a month of video costs
| Workload | Audio | Credits |
|---|---|---|
| One video, 12 minutes | 12 min | 100 |
| One lecture, 60 minutes | 60 min | 500 |
| A month, 30 videos | 3,000 credits | |
8.33 credits a minute of audio, billed by the millisecond. Word timestamps cost nothing extra.
A twelve-minute video, cued
Times shown are illustrative. The spans on a real recording are the model's.
For developers
The snippets send one recording with word timestamps and read the transcript, the spans, and the credits charged from the response.
AUDIO=$(base64 < meeting.m4a | tr -d '\n')
curl -X POST https://api.paxalabs.com/v1/stt \
--max-time 300 \
-H "Authorization: Bearer $PAXA_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"audio\": \"$AUDIO\", \"model\": \"paxa-stt-lite-v1-preview\", \"timestamps\": \"word\"}"import { readFile } from "node:fs/promises";
const audio = (await readFile("meeting.m4a")).toString("base64");
const response = await fetch("https://api.paxalabs.com/v1/stt", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAXA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ audio, model: "paxa-stt-lite-v1-preview" }),
// A long recording can run for minutes; give it room.
signal: AbortSignal.timeout(300_000),
});
if (!response.ok) throw new Error(`Transcription failed: ${response.status}`);
const { text, usage } = await response.json();
console.log(text, `${usage.credits} credits`);import base64
import os
import requests
with open("meeting.m4a", "rb") as file:
audio = base64.b64encode(file.read()).decode()
response = requests.post(
"https://api.paxalabs.com/v1/stt",
headers={"Authorization": f"Bearer {os.environ['PAXA_API_KEY']}"},
json={"audio": audio, "model": "paxa-stt-lite-v1-preview"},
# A long recording can run for minutes; give it room.
timeout=300,
)
response.raise_for_status()
body = response.json()
print(body["text"], body["usage"]["credits"], "credits")What the model was built to hear
Paxa STT Lite transcribes Thai and English, including sentences that switch language halfway. Its word spans are the segmentation of a script that has no spaces. It publishes no accuracy figure until the evaluation method is published beside it.
Common questions
- Does it output SRT or WebVTT?
- It outputs the transcript and word spans as JSON. Cutting cues and writing the caption file is a few lines in your code, and the line length stays yours.
- Can it caption a video in English?
- Set the language hint to en for an English recording. Thai words inside it are still transcribed as spoken.
- Does it translate the captions?
- The transcript is in the language spoken. For an English caption track from Thai audio, send the transcript to the translation API.
- What about a two-hour lecture?
- Split the audio at a pause into parts of up to 60 minutes, send them in parallel, and offset the spans of each part by its start time.
Start with free credits
Sign in with Google, GitHub, or Hugging Face and spend 100 one-time free credits on your own text.