TL;DR — Every ticket lists the episode's subtitles: one WebVTT file per language, in
langorder. An empty list means none yet, not an error. Native apps hand the URLs to the Player SDK or render the cues themselves; web players download the file and add the cues withaddTextTrack(). Subtitle URLs outlive the ticket; when one stops working, take the current URL from the next ticket.
Where they come from
| Field | Description |
|---|---|
subtitles[].lang |
Language code as delivered, for example en, vi, pt-BR. |
subtitles[].url |
Where to download the WebVTT file. |
subtitles[].format |
webvtt today. Skip a format you do not know. |
- Subtitles are not in the catalog; they come with each ticket. The languages present across your films are listed in
GET /config(subtitles.languages). - A subtitle attached or replaced on Wandura's side reaches tickets within 5 minutes.
- A replaced file gets a new URL, and the old one stops working. If a stored URL fails, take the current one from a fresh ticket.
- Subtitle URLs are public and long-lived: fine to cache per episode, not to publish.
- A subtitle that fails to load must never stop playback.
Native apps
Two options, both covered in the portal's Player SDK guide: give the URLs to the SDK's external-subtitle mode, or download the .vtt and draw the cues over the player yourself. The iOS and Android examples pass ticket.subtitles to one addSubtitles call.
Web players
Do not add the crossorigin attribute to the <video> element so you can use a <track>: it changes how the video itself is requested and can stop it from playing. Download the file with fetch and add the cues yourself:
/** One text track per subtitle of a ticket. A file that fails is skipped: subtitles never block playback. */
export async function addSubtitles(video: HTMLVideoElement, subtitles: Subtitle[], show = 'en'): Promise<void> {
for (const s of subtitles) {
if (s.format !== 'webvtt') continue; // unknown format: skip it
try {
const res = await fetch(s.url);
if (!res.ok) continue; // replaced since: the next ticket has the current URL
const track = video.addTextTrack('subtitles', s.lang, s.lang);
for (const c of parseVtt(await res.text())) track.addCue(new VTTCue(c.start, c.end, c.text));
track.mode = s.lang === show ? 'showing' : 'hidden';
} catch {
// network error: play without this language
}
}
}Done when
- Subtitles appear, and switching language works.
- An episode without subtitles plays without an error.
- A subtitle URL that answers
404is skipped, and playback continues.
Related
Updated 5 Oct 2026 · Change history (1)