IGTranscript

Why won't Instagram transcribe my video?

Nearly every "it won't transcribe" is one of five failures, and each one leaves a different signature, so you can usually identify yours before you change a single setting. Nothing was said in the clip — or the file carries no audio track at all, which fails earlier and in a different place. There is sound, but it is music rather than speech. There is speech, but the language picker is set to a language the model was not told to expect. The clip changes language part-way through, and one setting has to cover the whole file. Or the video cannot be reached at all, because the post is gone, the account is private, or you never held a file to begin with — and this page has no route to a post: its script contains exactly one fetch( and one import(, both aimed at the model and the library that runs it, and zero FormData, XMLHttpRequest, sendBeacon or POST. One thing all five share is cost: a three-minute clip holds the same 80.64 MB in the tab whether it turns out to be a music bed or an interview, because the audio is decoded before recognition starts and the decode has no idea what is in it.

InVideo WW

The five signatures in one picture

A five-question check. Down the left are the five questions to ask in order: does the file play with any sound, is anyone speaking, does the speech match the language picker, does the clip stay in one language, and do you hold the file yourself. On the right is the signature each failure leaves: the browser refuses to decode the audio, the model returns a non-speech annotation, the output is fluent nonsense in the wrong language, one language setting covers every slice of a clip that switched, or there is no route to the post at all. Which of the five failures is this? Ask the questions down the left, in order. The signature is on the right. 1. Does the file play with any sound at all? No audio track the browser refuses to decode 2. Sound — but is anyone speaking? Music only a non-speech annotation comes back 3. Speech — does it match the picker? Wrong language fluent nonsense, and no error at all 4. One language the whole way through? It switches mid-clip one setting covers every slice 5. Do you hold the file yourself? No route to the post deleted, private, or never saved
Questions one to four are about the audio you already hold and can all be answered by listening to the file once. Question five is about reach, and it is the only one this page cannot fix. The cost is identical across the first four: a three-minute clip holds 80.64 MB in the tab whether it turns out to be a music bed or an interview, because the decode finishes before recognition begins. The list behind question three is 3,832 bytes of generation_config.json declaring 99 language tokens, and the response that ends question five is 629,715 bytes whether or not the post exists.

Failure 1: nothing was said — and the two ways that fails

This is the failure people are most confident is not theirs, because the file plays perfectly on their machine. It splits into two cases that fail in different places. If the file has no audio track at all — the commonest cause is a screen recording made while the system output was muted, or a WebM exported with a picture and no sound — the failure happens before any model is loaded, because the browser will not decode what is not there. If the file has an audio track that simply contains no speech, the decode succeeds, the model runs, and the result panel is headed "No speech found" instead of "Transcript".

The measurement worth knowing here is that the browser does not tell these causes apart, and it does not tell them apart from a third one either. Measured in an ordinary browser tab on this machine, a WebM with a picture and no audio track, a 77-byte text file renamed to .mp4, and a valid 20-minute WAV all reject the decode with the same error: EncodingError, "Unable to decode audio data", code 0, with nothing in the error object that separates them. The third of those is not damage and not silence — it is size: the same 20-minute file, held as 48,000 Hz stereo 32-bit float, is 460.8 MB before anything is resampled, and 537.6 MB once the 16,000 Hz mono copy exists alongside it.

Three different causes collapsing into one identical message. A file with no audio track, a file in a codec the browser cannot read, and a file too large for the tab all reject with the same EncodingError, the same text and code 0, and nothing in the error object separates them. Underneath is the cheapest way to tell them apart: play the file and confirm there is sound, then cut a much shorter clip from the same recording. If the short clip transcribes, the file was fine and the limit was memory; if it fails identically, the audio is missing or the codec is unsupported. Three different causes, one identical message The browser will not say which of the three it was. No audio track at all a screen recording made with the sound muted A codec the browser cannot read the container is not one it decodes Too large for the tab not damage and not silence — it is size EncodingError "Unable to decode audio data" code 0 nothing in the object separates the three The cheapest way to tell them apart Play the file and confirm there is sound in it. Then cut a much shorter clip from the same recording and run that. Short clip transcribes → the file was fine and the limit was memory. Short clip fails identically → the audio is missing, or the codec is one the browser does not have.
Because the browser reports a missing audio track, a codec it cannot read and a file too large for the tab with the identical EncodingError and code 0, naming only one of them would be a false statement about the other two — which is why the page names all three instead of guessing at one. Measured here, a WebM with a picture and no audio track, a 77-byte text file renamed to .mp4 and a valid 20-minute WAV all reject the decode the same way. The third of those is not damage and not silence but size: the same 20-minute file held as 48 kHz stereo 32-bit float is 460.8 MB before anything is resampled, and 537.6 MB once the 16 kHz mono copy exists alongside it.

Because the browser will not say which of the three it was, the honest move is to check them in the cheapest order. Play the file and confirm there is sound in it. Then try a much shorter clip cut from the same recording: if the short one transcribes, the file was fine and the limit was memory; if the short one fails identically, the audio is missing or in a codec the browser does not have.

Failure 2: there is sound, but it is music rather than speech

A Reel built around a music bed is the case that used to look like a bug rather than a failure. Whisper does not return an empty string when it finds no speech; it returns an annotation, and an annotation is a truthy string, so a plain test for "did we get any text" passes and the page reports success. Measured here: a clip carrying a music bed and no speech at all came back headed "Transcript" with "2 words", the two words being "(smooth music)".

The annotations arrive in two families, and the page has to strip both. Square brackets produce things like [BLANK_AUDIO], [Music] and [Applause]. Round brackets produce things like (smooth music), (upbeat music) and (birds chirping) — and the round-bracket family is what a music bed actually comes back as, which is why knowing only about the square one was not enough. Asterisks are deliberately left alone: *music* is not an annotation, and a transcript is allowed to contain an asterisk. Once both families are stripped, a music-only file reports "No speech found" and says why.

None of this saves memory, and it is worth being clear about that. A three-minute music bed costs the tab exactly what a three-minute interview costs — 69.12 MB of decoded 48,000 Hz stereo plus 11.52 MB of resampled 16,000 Hz mono, 80.64 MB in total — because the decode runs to completion before the model is given anything to recognise.

Failure 3: the language picker is set to the wrong language

The language picker on this page is not a hand-written list, and that matters to this failure. It is read from the model's own generation_config.json — the file the model itself uses to decide which language tokens exist — so the picker lists exactly the languages the loaded checkpoint accepts and cannot drift away from the model if the checkpoint is ever changed. Measured on this machine: the default checkpoint's file is 3,832 bytes and declares 99 language tokens; the smaller checkpoint's file is 3,772 bytes and declares the same 99. The tokens themselves look like <|en|> and <|zh|>, and the display names beside them come from the browser's own locale data rather than a second hand-written table.

What makes this failure hard to spot is that it produces no error. The model still runs, the panel is still headed "Transcript", and the output is either fluent text in a language nobody in the video was speaking, or a short string of misheard words. The run takes about as long and costs about as much as a correct one: the same 1.92 MB per 30-second slice, the same 26.88 MB for a one-minute clip. Nothing about the result tells you that the input was wrong rather than the audio.

The fix is to match the picker to what you hear rather than to what you expect, and to re-run once with the corrected value instead of editing the output. If you do not know what language the clip is in, the picker's full list of 99 tokens is the place to look — it is the model's own inventory, not a marketing claim about coverage.

Failure 4: the clip changes language part-way through

One language value is passed for the whole run. The call the page makes is language: lang together with task: 'transcribe', return_timestamps: true and chunk_length_s: 30 — a single language, applied to a file that has been cut into 30-second slices. At 16,000 Hz mono, one slice is 480,000 samples, which is 1.92 MB; a three-minute Reel is six such slices, and all six are recognised under the same setting.

One run of a clip that changes language drawn as six slices. The first three are English and the last three are Spanish, but a single language value is passed for the whole run, so all six are recognised under the setting that was chosen rather than under the language actually spoken. Below, the same clip cut into two files at the change, each run with its own setting. One language value covers the whole run, not each slice Nothing detects a switch, so both halves are recognised under the setting you picked. one run, one setting English English English Spanish Spanish Spanish one language value, applied to every slice in the file split at the change English run Spanish run two files, two settings, and each one is measured from its own start The picker is a parameter, not a detector — and cutting also halves what one run has to hold.
The six boxes are the slices the file is cut into before anything is recognised: at 16,000 Hz mono one slice is 480,000 samples and 1.92 MB, and a three-minute Reel is six of them. One language value is passed for the whole run — the call carries language: lang together with task: 'transcribe', return_timestamps: true and chunk_length_s: 30 — so the last three boxes are recognised as if they were the language in the first three. Nothing in the page detects the switch, because the language is a parameter rather than something inferred per slice. Cutting the same clip into two 90-second files makes each half its own run with its own setting, and it also drops the memory a run has to hold from 80.64 MB to 40.32 MB; the two transcripts join afterwards because each run returns timestamps measured from the start of the file it was given.

So a Reel that opens in one language and switches to another halfway does not get a mixed transcript — it gets whichever single language was selected, applied to both halves. Nothing in the page detects the switch, because the language is a parameter you set rather than something inferred per slice. This is also why a wrong guess on this failure looks exactly like Failure 3: no error, a clean panel, and text that is wrong in a way the page cannot see.

The workable route is to split the audio at the point where the language changes and run each half with its own setting. Cutting a three-minute clip into two ninety-second files keeps the memory per run down as well — each half holds 40.32 MB rather than the 80.64 MB the whole file costs — and the two transcripts can be joined afterwards, because each run returns timestamps measured from the start of the file it was given.

Failure 5: the video cannot be reached at all

The last failure is not about the audio, and it is the one this page cannot fix. If the post has been deleted, if the account is private, or if you never had the file in the first place, there is no route from here to those words. That is structural rather than a limitation of the model. The script that does the work is 22,349 bytes and contains exactly one fetch( and exactly one import(, aimed at the model's language list and the recognition library respectively; it contains zero FormData, zero XMLHttpRequest, zero sendBeacon and zero POST requests, and the 16 deployable files of this site contain zero <form> elements in 190,398 bytes. A page that cannot construct a request has no route by which a post could be fetched, so "just give it the link" is not a gap that could be closed by trying harder.

It is worth seeing what Instagram actually returns, because it explains why the link route is not merely restricted but empty. Measured on 12 October 2026 with a logged-out request and a Chrome user-agent: a Reel URL returns HTTP 200 and 629,715 bytes of HTML. A fabricated ID that has never existed returns exactly the same 629,715 bytes — the same 79 script tags, the same zero <video> elements, the same zero occurrences of video_url, and identical counts of the markers login (19), Login (4), signup (6) and logged_out (4). Byte for byte, the response does not depend on whether the post exists, which means a tool that reads that response cannot tell a deleted Reel from a live one either.

What is left is the file. If the Reel is yours, it is in your own export or your camera roll. If it is not yours and the post still exists, downloading it is the step that has to happen somewhere other than here. If the post is gone, nothing on this page can recover it, and any tool that claims otherwise is describing a route that does not exist.

How to tell which of the five you have

  1. Play the file once and listen. No sound at all points at Failure 1's first case; only music points at Failure 2; speech you cannot quite follow in the language you expected points at Failure 3.
  2. Read the heading of the result panel. "No speech found" means the decode succeeded and the model found nothing it would call words. A decode error means the browser refused the file, which is Failure 1's first case or a file too large for the tab — 537.6 MB of decoded audio is the ceiling a 20-minute clip would ask for.
  3. Check the picker against what you actually hear, not against the language you assumed. This is the only one of the five that produces a confident, fluent, wrong answer, and the only one where re-running with one setting changed is the whole fix.
  4. Listen for a language change inside the clip. If the speaker switches part-way, split the audio there and run each part with its own setting rather than trying to make one run cover both.
  5. Confirm you hold the file. If the only thing you have is a link, stop here: with zero request-constructing primitives in the script, no setting on this page can turn a post into audio, deleted or otherwise.

What the error message can and cannot tell you

The error text on this page names three causes rather than one, and that is deliberate rather than vague. Because the browser reports a missing audio track, a codec it cannot read and a file too large for the tab with the identical EncodingError and code 0, naming only one of them would be a false statement about the other two — the page used to tell someone with a silent screen recording that their file was damaged or too long. Naming all three, and then telling you how to find out which it was by testing a shorter clip, is the most that the information available in the tab supports.

Everything the page can measure, it reports. The result panel gives the duration of the audio in seconds, the word count and segment count when there is speech, the time the recognition took, and which of the two checkpoints produced it. A panel that reports a duration, a word count and a segment count is telling you that the audio was found and that the model produced text — so if the text is still wrong, the setting is the place to look rather than the file. A panel headed "No speech found" is telling you the opposite, and a decode error is telling you the file never got that far. None of those three states is ambiguous, which is why the fifth failure is the only one where the answer is simply that the audio is not reachable from here.

Last checked: 12 October 2026. The counts of this site's own files were taken on this machine on that date rather than remembered: the script is 22,349 bytes, the stylesheet is 9,455 bytes, the 16 deployable files total 190,398 bytes, and the script contains one fetch(, one import(, and zero FormData, XMLHttpRequest, sendBeacon or POST. The two generation_config.json sizes — 3,832 bytes and 3,772 bytes, each declaring 99 language tokens — were fetched on the same day. The Instagram figures were measured the same day with a logged-out request and a Chrome user-agent: HTTP 200, 629,715 bytes for both a Reel URL and a fabricated ID, zero <video> elements and zero video_url occurrences in either. The audio arithmetic is derived, not measured — Web Audio fixes a decoded sample at 32 bits, so one second of 48,000 Hz stereo is 48,000 × 2 × 4 = 384,000 bytes and the same second at 16,000 Hz mono is 64,000 bytes, and both buffers exist at once while the resample runs, giving 26.88 MB for one minute, 80.64 MB for three and 537.6 MB for twenty. The "2 words" music-bed result and the three identically-reported decode failures were measured in an ordinary browser tab on a two-core, four-gigabyte machine. Figures that could not be measured or derived are absent rather than estimated.

The mechanics behind the tab-memory figures are counted on the page about whether transcribing uploads the video. The ceiling that decides whether a long clip finishes at all is on the Reel length limit page, and what Instagram's own captions do and do not produce is on the page about Instagram's built-in captions. If the Reel is one you cannot open, the private Reel page covers the routes that still work, and if you are feeding more than one file through, bulk transcribing Instagram Reels covers what changes.