Back

Blog details

Multi-Language Captions and Transcripts: A Developer Guide

AIOZ Network
7 min readSeptember 08, 2026
aioz-streamguide

The Chapter vs Transcript API article covered how one transcript file gets uploaded and marked default. This is what actually happens once a video has transcripts in five languages and different viewers need different ones by default, and it turns out the real answer depends on a browser behavior most developers building this don't realize they're relying on.

TL;DR:

  • Each language gets its own VTT file uploaded through the Transcript API, one per BCP 47 language code, with a single is_default flag that's global to the video, not personalized per viewer.
  • That global default sounds like a real limitation for serving different languages to different visitors, but the HTML spec itself hands most of the actual work to the browser: per MDN, a track marked default is "enabled unless the user's preferences indicate that another track is more appropriate."
  • The practical implication: upload every language a video needs, pick one sensible fallback as is_default, and let the browser's own language matching handle the rest, rather than trying to flip the default per request based on detected locale.
  • Regional BCP 47 variants (en-US vs en-GB, pt-BR vs pt-PT) matter when spelling or vocabulary genuinely differs, not as a default habit, most captions work fine tagged with a primary language code alone.
  • Nothing in AIOZ's documentation mentions Accept-Language headers or server-side locale detection, this is entirely a client-side, browser-native mechanism, not an AIOZ Stream feature to configure.

What multi-language actually requires, quickly

One call per language is the whole upload story: a POST to the Transcript API's create endpoint, per language code, each with its own VTT file. A video with English, Spanish, and Japanese transcripts is three separate uploads, three separate BCP 47 codes, not one multi-language file or a combined format, there's no single file format that carries multiple languages at once the way, say, a multi-track audio container might. Exactly one of those can be flagged is_default via the API's PATCH endpoint at any given time, AIOZ's own documentation is direct about what that flag does: "the default transcript is the transcript the player loads by default." Singular, one flag, one video, this isn't per-viewer or per-session, it's a stored property of the media object itself, the same way a video's title or description is one value shared by everyone who requests it, not something the API varies per request.

Video player interface showing multiple language subtitle options

The real constraint: one default, not one per viewer

This is worth being direct about rather than glossing over: nothing in AIOZ's Transcript API documentation mentions Accept-Language headers, geo-detection, or any mechanism for showing French viewers French by default and English viewers English by default automatically. The is_default flag is one setting, and whoever set it last is what every viewer gets unless they manually pick a different track themselves. A naive fix, detecting each viewer's locale server-side and calling the PATCH endpoint to flip the default before serving the page, technically works but creates a real race condition: two viewers with different locales requesting the same video near-simultaneously would each be changing a setting the other one just changed, with no guarantee either sees the right language.

Why the browser already handles most of this

The HTML specification for text tracks describes exactly the scenario multi-language captions run into, and hands the actual per-viewer decision to the browser, not the server. Per MDN's own documentation of the default attribute on a video's text track: "This attribute indicates that the track should be enabled unless the user's preferences indicate that another track is more appropriate." That's the mechanism that actually solves the per-viewer problem, not AIOZ's API. If every available language transcript is exposed to the player as its own track, a browser that knows the viewer's language preference, from their OS or browser language settings, is specced to prefer a matching track over whatever's marked default, not the other way around. The is_default flag matters specifically as the fallback for a viewer whose language preference doesn't match anything available, not as the primary mechanism serving each viewer the right transcript.

BCP 47 in practice: when regional variants actually matter

Both the Chapter and Transcript APIs accept regional variants like en-US or fr-CA alongside primary tags like en or fr, and it's worth having an actual rule for when to bother with the more specific tag rather than defaulting to it out of habit. Regional variants earn their keep when the content itself genuinely differs, British and American English spelling and vocabulary diverge enough that a captions team might localize separately, and Brazilian and European Portuguese differ enough in vocabulary that treating them as one language produces captions that read oddly to one audience or the other. For a video where the transcript would read identically regardless of region, the primary tag alone is the simpler, equally correct choice, extra regional variants only add value when there's an actual second version of the text to justify them. The W3C's own internationalization guidance states this as a general rule for language tags, not something specific to captions: "you should only use a region subtag if it contributes information needed in a particular context to distinguish this language tag from another one; otherwise leave it out," giving the same en-GB example as a case where the distinction earns its keep, spelling, while noting that a region subtag on, say, Japanese is unlikely to matter "unless you are intentionally contrasting it with Japanese spoken in other parts of the world." The golden rule the guidance states directly, keep the tag as short as possible and only extend it when the extension actually distinguishes something, applies to caption files exactly as it does to any other tagged content.

A practical multi-language workflow

Given all of the above, the workflow that actually holds up in production is simpler than trying to out-engineer the global-default constraint: upload a transcript for every language the video genuinely needs to support, pick whichever language the majority of the expected audience speaks as is_default, a true fallback choice, not a personalization attempt, and let every uploaded track render as its own option in the player. That leaves the browser's own spec-mandated preference matching to route each viewer to their actual language when one is available, with the single global default only ever surfacing for a viewer whose preference doesn't match anything on offer. Trying to dynamically rewrite is_default per request solves a problem the browser was already going to solve correctly, while introducing a real race condition that wasn't there before.

Concretely, for a video with English, Spanish, and Japanese transcripts aimed primarily at an English-speaking audience: upload all three via the Transcript API, one create call per language, then set en as is_default once, and leave it. A Spanish-speaking viewer whose browser is configured for Spanish gets the Spanish track automatically, per the same MDN-documented preference matching, without AIOZ Stream or the integrating application doing anything per-request to make that happen. The en default only actually surfaces for a viewer whose browser language doesn't match any of the three uploaded tracks, a French-language browser, for instance, with no French transcript available, at which point falling back to the primary audience's language is a reasonable default rather than an arbitrary one.

Frequently Asked Questions

Can AIOZ Stream show different default captions to different viewers automatically?
Not through the API. The is_default flag is a single, global setting per video; per-viewer language selection happens through the browser's own text-track preference matching, not through anything AIOZ Stream configures server-side.

Should I dynamically change is_default based on each viewer's detected locale?
Generally no. It creates a race condition between concurrent viewers with different locales and solves a problem the browser's native track-selection behavior already handles for any track that's actually available as an option.

How does a browser decide which caption track to show if I don't set anything?
Per the HTML spec, a browser prefers a track matching the user's own language preference over the one marked default, falling back to the default track only when no better match exists among the available options.

Do I need regional variants like en-US and en-GB, or is a plain language code enough?
A plain code like en is enough unless the transcript text genuinely differs by region, spelling, vocabulary, or dialect differences real enough to justify a separately localized file.

How many transcript files can one video have?
One per language code, per the Transcript API's own limit, at most one transcript per BCP 47 language tag for a given media object.

Does this same logic apply to chapters, not just transcripts?
Chapters don't have an is_default field or a default concept at all in AIOZ's API, this default/fallback discussion is specific to transcripts.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

Best OBS Encoder Settings for 1080p and 720p (AIOZ Stream)

Choose OBS encoder settings for AIOZ Stream: the documented 1080p30 values, the missing 720p figure, NVENC vs x264, keyframes, 60 fps and a test procedure.

aioz-streamguide
6 min readOctober 16, 2026
blog thumbnail

OBS Studio Setup Guide for AIOZ Stream: RTMP, Scenes and Output Settings

Set up OBS Studio for AIOZ Stream: build a scene, connect with a Custom RTMP service and stream key, enter the documented output settings, and confirm the stream is live.

aioz-streamguide
6 min readOctober 13, 2026
blog thumbnail

How to Start a Livestream on AIOZ Stream: OBS and Mobile Setup

Seven steps to go live on AIOZ Stream with OBS or PRISM: stream key, session form, RTMP credentials, bandwidth math, and the first two minutes after you start.

aioz-streamguide
6 min readOctober 09, 2026
blog thumbnail

Live Streaming on AIOZ Stream: The Complete Guide

How live streaming on AIOZ Stream works: stream keys, sessions and saved media, OBS and PRISM setup over RTMP, restreaming, statistics, archiving, and what the docs leave out.

aioz-streamguide
7 min readOctober 06, 2026
blog thumbnail

What Is a Web3 Streaming Platform?

What separates a real web3 streaming platform from marketing language, and how AIOZ Stream's DePIN network, on-chain payments and W2E rewards measure up.

aioz-streamguide
6 min readOctober 02, 2026
blog thumbnail

Accessibility in Video Streaming: What WCAG Actually Requires

WCAG's five real video accessibility rules, why auto-captions usually fail them, what AIOZ Stream actually supports, and how the 2026 ADA deadline changes affect compliance.

aioz-streamguide
6 min readSeptember 29, 2026