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.
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.
- The picker offers 99 languages and no way to ask for detection. The list is built from
lang_to_idin the model’s owngeneration_config.json, fetched on 30 October 2026: 99 keys, ids 50259 to 50357, consecutive, and identical in both checkpoints this page offers.<|en|>is 50259, the first of the 99;<|es|>is 50262, the fourth. There is no entry for “auto” or “unknown” in that file, so there is none in the picker either. - The task slot is pinned; the language slot is the one left open. The same config carries
decoder_start_token_id50258 andforced_decoder_idsof[[1, null], [2, 50359]]. Position 2 is fixed at 50359 and app.js only ever asks fortask: 'transcribe'; position 1 is null, and 50259 — the first language id — is the value that goes there. One token, at the front of each window’s decoding, out of the 99 the picker can put in it. - Detection is a branch this page never takes. The library documents the alternative at line 1647: the language “Default is
null, meaning it should be auto-detected.” Line 279 never passes null, because the picker always has a value — line 96 falls back toenwhen the stored choice is not in the list, and the start-up call at line 557 asks forenexplicitly. The condition the library describes for detection is therefore never met, whatever the file contains.
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.
- Window counts follow directly. 60 seconds is 3 windows, 120 seconds is 6, 161.2 seconds is 8, 600 seconds is 30. The 600-second figure is checkable against a real run on this machine: 251.5 seconds of recognition for a 600.3-second file, which is 8.38 seconds per window across 30 of them, and 111 segments, or 3.7 per window.
- Each window is 1,920,000 bytes of float32 audio. 480,000 samples at 4 bytes each, handed to the model as it is. The 161.2-second file is 2,579,200 samples of real audio, but its 8 windows feed the model 3,840,000 samples — 15,360,000 bytes, or 1.489 times the length of the file. The overlap is trimmed when the windows are merged back into text, but it is decoded first.
- A two-minute Reel has one or two windows that hold both languages. With a switch at 60 seconds, exactly 1 of the 6 windows contains audio from both sides; because the step is 320,000 samples, a switch that lands 5 seconds off a window start, at 45 seconds, puts 2 of the 6 in that position. The other 4 or 5 windows are clean, which is why a mixed Reel often comes back looking almost right.
num_frames inside the loop at line 1877.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.
- There is no error path for a wrong language. The panel decides between “Transcript” and “No speech found” by stripping the bracketed and parenthesised annotations from the output and testing whether anything is left (lines 412 to 416 of app.js). Wrong-language output is long and confident, so it passes that test and is presented as a transcript. The only place the picker is even mentioned as a cause is the text shown when the result is empty.
- The output has nowhere to record a language. Each segment is built with exactly three keys —
start,end,text— at line 338 of the 22,349-byte app.js, and the three writers read only those. So a mixed-language run produces one flat text, and neither the .srt nor the .vtt has a field in which a per-line language could be stored, even if the model had reported one. - The timestamps cannot rescue it either. The timestamped view puts a fixed 12-character stamp in front of each line and nothing else, so the only way to find where the language changes is to read the text and guess — which is exactly the judgement the transcript was supposed to save you.
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.
- speakapp.com states the one-language case as the general case. Its Instagram page says: “The model handles 50+ languages and detects them automatically, so a video in Spanish, Portuguese, Hindi or Japanese works exactly the same way an English one does.” That is a claim about a video in one language; it says nothing about a video in two, and detection is the one thing this page’s build does not do.
- Its testimonial describes three videos, not one. “Auto language detection is the killer feature. I drop in Japanese, Spanish, and Korean Instagram videos and the transcripts come back correctly without any setup.” Three files, three languages, one language each — the case a single-language model handles well.
- wayin.ai comes closest, and it is a different feature. Its Reels summariser says “The tool can even generate bilingual subtitles for your need.” That is a second language produced by translation from one detected source language, which is a different operation from transcribing a file whose speakers change language mid-sentence.
- getthescript.app lists Spanish as an output language. “Transcribe and translate summaries into English, Spanish, Chinese, Japanese, and more.” Across its 52,963 characters of body text, Spanish appears twice, both times in a list like this one; 0 of the 59 files describes what happens when the switch is inside the file.
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.
- Split at the switch and run each half. A 120-second Reel cut into two 60-second files is 3 windows plus 3 windows — 6 in total, exactly the number the single file needed. You pay one extra decode of the second half, one extra click, and two exports; you gain a file in which every line is in the language you asked for.
- Or run the whole file twice, once per language, and keep the good lines. That is 6 windows twice, 12 in total, and it leaves you with two overlapping transcripts and the job of deciding line by line which one to keep — work the three-key segment format gives you no help with.
- If the file cannot be split, pick the language that most of the audio is in. The number of windows does not change with the choice, so the only thing being minimised is how many of them are decoded in the wrong language: at a switch at 60 seconds that is 1 of 6 either way, and at 45 seconds it is 2 of 6. Picking the majority language does not fix the minority, it just keeps the damage inside the windows that actually contain it.
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.