IGTranscript

What happens to an Instagram transcript when the Reel mixes English and Spanish?

One language is chosen for the whole file, and every window is decoded with it. The picker on this page holds 99 languages — token ids 50259 to 50357, with no “detect” entry among them — and whichever one is selected is handed to the model once, at line 279 of app.js, before the first 30-second window is cut. A Reel that starts in English and switches to Spanish halfway therefore comes back as one block of text in which the second half was pushed through an English decoder: confident nonsense rather than an error, and nothing in the .txt, .srt or .vtt marks which line was which. On a two-minute Reel the switch falls inside 1 of the 6 windows the audio is divided into. The repair is not a setting. Split the file at the switch and run each half — 3 windows each, 6 in total — or run the whole file twice, which is 12.

InVideo WW

The rest of this page is the evidence for that: where the language value is read and how far it travels (line 1809 of the 147,189-byte recognition module, not app.js), how many windows it ends up covering on a Reel of a given length (a 30-second window that advances 20 seconds at a time, 480,000 samples each), what a wrong language actually returns (a measurement recorded on this site: 404 words where 54 were spoken), and what the three sites that outrank this one say about mixed-language input across 478,446 characters of their own copy, in which the phrase “code-switching” appears 0 times.

One language, chosen before the first window

The picker is read once. Line 257 of app.js takes $('lang').value into a local variable, and line 279 passes it to the model as language: lang, beside task: 'transcribe' and chunk_length_s: 30. The windowing loop is not in app.js at all — it lives in the recognition library, where those arguments become a generation_config object at line 1809 of the 147,189-byte pipeline module, once, before any audio is cut. Inside the loop over windows the module changes exactly one field, num_frames, at line 1877, and then spreads the same object into model.generate() at line 1882. A file that produces 30 windows is therefore decoded with one language 30 times, not with 30 decisions.

How many windows that one language has to cover

The window size is not a guess: it is three constants from the module. The window is 16000 × 30 = 480,000 samples; the stride defaults to a sixth of the chunk, 30 ÷ 6 = 5 seconds = 80,000 samples; and the step is the window minus both strides, 480,000 − 160,000 = 320,000 samples, which is 20 seconds of audio. Each window is 30 seconds wide and the file advances 20 seconds at a time, so consecutive windows overlap by 10 seconds and the last one runs past the end of the audio.

Six overlapping windows over a 120-second Reel, with the language switch at 60 seconds falling inside the third window. Every row is decoded with the same single language token taken from the picker. Six windows, one language token A 120-second Reel cut into 30-second windows that advance 20 seconds at a time. English Spanish w1 w2 w3 both languages, one window w4 w5 w6 past the end 0 s 30 60 90 120 one token — the one in the picker the same token is used for w1 through w6
Where the two languages meet. Each row is one 30-second window of a 120-second Reel, and the rows advance 20 seconds at a time, so neighbours overlap by 10 seconds; the sixth runs 10 seconds past the end of the audio and is clipped. The dashed red line is the point where the speech changes language, at 60 seconds, and it falls inside w3 — 1 of the 6 windows holds audio from both sides. The bar at the bottom is the only language decision in the whole run: one token, taken from the picker before the first window is cut and reused unchanged for all six, because the module builds its generation config once at line 1809 and only replaces num_frames inside the loop at line 1877.
A four-step chain: the language picker is read once in app.js, passed to the model, turned into one generation config before any audio is cut, and then reused for every window because only the frame count changes inside the loop. One language, decided before the first window The value is read once and reused; no step in the chain looks at the audio to choose it. The picker: one id out of 99 50259 to 50357, consecutive, no entry for auto or unknown app.js 257, then 279 Read once into a local variable, then passed as language Pipeline 1809: one generation config Built once, before any audio is cut Auto-detect exists in the library but null is never passed, so the branch is never taken Window loop 1877 Only num_frames changes; the same config is spread into every generate call Every window, the same token one decision, repeated per window
The language is not a per-window decision. Line 257 of app.js takes the picker value into a local variable and line 279 passes it as language beside chunk_length_s: 30; the recognition library turns those arguments into one generation_config at line 1809 of its 147,189-byte pipeline module, before any audio is cut, and inside the loop over windows it changes exactly one field — num_frames, at line 1877 — before spreading the same object into model.generate(). A file that produces 30 windows is therefore decoded with one language 30 times, not with 30 decisions. The picker offers 99 languages, token ids 50259 to 50357, with no “auto” or “unknown” entry, so the detection branch the library documents at line 1647 is never reached: line 96 falls back to en and the start-up call at line 557 asks for en explicitly.

What a wrong language returns, and why it never looks like an error

The failure is quiet. A measurement recorded on this site’s own Languages section: an English clip that contains 54 words, run with the picker set to Spanish, came back as 404 words of repeated Spanish — 7.481 times the word count of the speech, or 350 words that were never said. Nothing in that result is flagged. It is a transcript with a word count, a duration and a timestamp for every line, and every one of those numbers is real; only the words are wrong.

What the three pages that outrank this one say about it

Across the 59 files of competitor copy held for comparison — 478,446 characters once the heading lists and the scraper’s metadata are stripped, because those are not sentences a reader sees — the word “Spanish” appears 11 times, and the phrases “code-switching”, “code switch”, “mixed language”, “two languages”, “both languages” and “Spanglish” appear 0 times between them. The 10 Instagram pages among those files account for 126,491 characters of that total. Every mention of Spanish is a list of supported languages, not a description of a file that uses two.

Two routes that keep both languages

Since the language is a property of the run rather than of the window, the fix has to be applied outside the page. Both routes below are arithmetic, not opinion: the window counts come from the same three constants, and they show that splitting the file is free in model work and costs only a second decode.

Does this page detect the language of my Reel?

No. The picker holds 99 languages — token ids 50259 to 50357 — and every one of them is a specific language; there is no “detect” entry to choose, because the list is built from the model’s own lang_to_id and that file contains no such key. English is what the picker falls back to when nothing else is stored, so a Spanish-only Reel is transcribed as English unless you change it first.

Will a mixed Reel fail, or just come back wrong?

It comes back wrong, and it comes back complete. A wrong language produces long, fluent, incorrect text rather than an empty result, so the panel shows “Transcript” with a word count and timestamps. The measurement recorded on this site is 404 words where 54 were spoken — 7.481 times the real count — and nothing in the output marks those 350 extra words as suspect.

Can I get one transcript with each language labelled?

Not from this tool. Every segment is built with three keys — start, end and text — and the subtitle writers read only those, so no export has a field for a per-line language. What you can do is run each half separately and keep the two files apart; that gives you the label by filename rather than by line.

Does splitting the file cost more processing?

Almost nothing. Two 60-second halves are 3 windows each, 6 in total, which is the same 6 windows the 120-second file needed on its own — the step is 320,000 samples either way. What you add is one extra decode pass and one extra run of the page; the model itself is already loaded, and line 270 skips the download when the same checkpoint is still in memory.

What if the Spanish is only one sentence in a long English Reel?

Then the damage is bounded by the windows, not by the sentence. A single sentence falls inside 1 of the 6 windows of a two-minute Reel, and inside 1 of the 30 windows of a ten-minute one, so at most one window’s worth of text is decoded in the wrong language — but the merge has no way to tell you which line it was, so you still have to read for it.

Last checked: 30 October 2026. Measured on this machine, from the deployed files: app.js is 22,349 bytes, with the picker read at line 257, language: lang at line 279, the en fallbacks at lines 96 and 557, the three-key segment at line 338, and the empty-result test at lines 412–416. The windowing constants are quoted from the recognition module cached here (147,189 bytes): generation_config built at line 1809, num_frames at line 1877, generate() at line 1882, and the auto-detect sentence at line 1647. The 99 languages, the id range 50259–50357 and the forced_decoder_ids pair were read from the models’ own generation_config.json, fetched on 30 October 2026, and both checkpoints carry identical values. Every window count and byte figure is arithmetic on those constants and was printed and re-checked with Python before it was written here: 480,000 samples a window, 80,000 a stride, a 320,000-sample step, 1,920,000 bytes a window, and 3,840,000 samples fed against 2,579,200 of real audio for the 161.2-second file. The 251.5 seconds, 111 segments and 8.38 seconds per window come from a real 600.3-second run on this machine on 27 October 2026. The 404-against-54 words is the measurement already recorded in this site’s own Languages section, not a new one. What has not been measured here is a real mixed-language file pushed through the page — the failure mode described above is the source path plus that wrong-language measurement, and I am not claiming a word-level error rate for bilingual audio. The competitor counts cover 59 files and 478,446 characters of body text held in this site’s benchmark directory, counted after the heading lists were stripped; the quoted sentences are verbatim from those files.

If the language is simply set wrong rather than mixed, why Instagram will not transcribe your video covers the five failures that look alike, and how accurate an Instagram transcript is covers how to check the words you did get. The speaker labels page covers the fourth key this tool does not have, the timestamps page covers the 12 characters in front of each line, and the long Reel page covers what 30 windows of waiting actually costs.