Add subtitles to video
Two approaches: burn-in (hardcoded into the video pixels) or sidecar (separate VTT/SRT file served alongside the video). Burn-in works everywhere. Sidecar lets viewers toggle captions on and off.
“Lectora” (an online learning platform like Udemy) needs captions on every course video for accessibility compliance.
Burn-in subtitles
API
ittybit video \
-i https://lectora-app.com/courses/intro-to-python.mp4 \
--subtitle_url https://lectora-app.com/courses/intro-to-python.vtt \
--subtitle_style burn_in \
--format mp4const task = {
input: 'https://lectora-app.com/courses/intro-to-python.mp4',
kind: 'video',
options: {
subtitle_url: 'https://lectora-app.com/courses/intro-to-python.vtt',
subtitle_style: 'burn_in',
format: 'mp4',
},
};
const res = await fetch('https://api.ittybit.com/jobs', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(task),
});
const data = await res.json();import requests
task = {
"input": "https://lectora-app.com/courses/intro-to-python.mp4",
"kind": "video",
"options": {
"subtitle_url": "https://lectora-app.com/courses/intro-to-python.vtt",
"subtitle_style": "burn_in",
"format": "mp4",
},
}
res = requests.post(
"https://api.ittybit.com/jobs",
headers={"Authorization": f"Bearer {api_key}"},
json=task,
)
data = res.json()TASK='{
"input": "https://lectora-app.com/courses/intro-to-python.mp4",
"kind": "video",
"options": {
"subtitle_url": "https://lectora-app.com/courses/intro-to-python.vtt",
"subtitle_style": "burn_in",
"format": "mp4"
}
}'
curl -X POST https://api.ittybit.com/jobs \
-H "Authorization: Bearer $ITTYBIT_API_KEY" \
-H "Content-Type: application/json" \
-d "$TASK" CLI
ittybit video \
-i intro-to-python.mp4 \
-o intro-to-python-subtitled.mp4 \
--subtitle_url intro-to-python.vtt \
--subtitle_style burn_in
Sidecar subtitles
Sidecar keeps the video untouched and produces a separate WebVTT file. Your player loads it via a <track> element.
ittybit video \
-i https://lectora-app.com/courses/intro-to-python.mp4 \
--subtitle_url https://lectora-app.com/courses/intro-to-python.srt \
--subtitle_style sidecar \
--subtitle_format vttconst task = {
input: 'https://lectora-app.com/courses/intro-to-python.mp4',
kind: 'video',
options: {
subtitle_url: 'https://lectora-app.com/courses/intro-to-python.srt',
subtitle_style: 'sidecar',
subtitle_format: 'vtt',
},
};
const res = await fetch('https://api.ittybit.com/jobs', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(task),
});
const data = await res.json();import requests
task = {
"input": "https://lectora-app.com/courses/intro-to-python.mp4",
"kind": "video",
"options": {
"subtitle_url": "https://lectora-app.com/courses/intro-to-python.srt",
"subtitle_style": "sidecar",
"subtitle_format": "vtt",
},
}
res = requests.post(
"https://api.ittybit.com/jobs",
headers={"Authorization": f"Bearer {api_key}"},
json=task,
)
data = res.json()TASK='{
"input": "https://lectora-app.com/courses/intro-to-python.mp4",
"kind": "video",
"options": {
"subtitle_url": "https://lectora-app.com/courses/intro-to-python.srt",
"subtitle_style": "sidecar",
"subtitle_format": "vtt"
}
}'
curl -X POST https://api.ittybit.com/jobs \
-H "Authorization: Bearer $ITTYBIT_API_KEY" \
-H "Content-Type: application/json" \
-d "$TASK" Burn-in vs sidecar
| Burn-in | Sidecar | |
|---|---|---|
| Viewer can toggle | No | Yes |
| Works in all players | Yes | Needs <track> support |
| Multi-language | One language per file | Multiple VTT files |
| File size | Larger (re-encoded) | Original + small VTT |
| Social media | Required | Not supported |
Use burn-in for social clips where players don’t support tracks. Use sidecar for web players where you want toggle and multi-language support.
Supported subtitle formats
| Format | Extension | Notes |
|---|---|---|
| WebVTT | .vtt | Web standard, supports styling |
| SRT | .srt | Widely supported, no styling |
| ASS/SSA | .ass | Advanced styling, burn-in only |
Pass any of these as the subtitle_url. For sidecar output, set subtitle_format to vtt or srt.