IGTranscript

Instagram transcript: SRT or VTT — which file do you need?

Take SRT unless something asks you for VTT by name. The two files hold the same cues in the same order and differ by 8 bytes of header, one character in each timestamp — a comma in SRT, a period in VTT — and the escaping of three characters. Measured on this machine by running this site’s own writers, 100 cues of one character each come out as 3,591 bytes of .srt and 3,599 bytes of .vtt. SRT is the file an editor imports and an upload box accepts; VTT is the file a browser loads through a <track> element, and a VTT without its 8-byte header is not a VTT at all.

InVideo WW

The rest of this page is the arithmetic behind that — where the 8 bytes sit, what a cue costs before any words are written, why one file escapes & and the other refuses to, what happens when every cue is zero length, and what the three pages that outrank this one say about the choice across 111,520 characters of their own Instagram copy. It is one gap and one answer: if you already have the words and only want to know which file to hand to which program, the paragraph above is the whole of it.

The difference is eight bytes, a comma and a period

Both writers are six lines of code in the same file. buildSrt() at line 382 and buildVtt() at line 385 emit the same block for every cue — an index, a timing line, the text, a newline — and differ in three places that can be counted. Running them on 100 cues of one character each, on this machine, gives 3,591 bytes for the .srt and 3,599 bytes for the .vtt.

The same single cue written in both formats. On the left an SRT file starts with the index line, then a timing line with a comma before the milliseconds, then the text. On the right a VTT file has one extra line at the top reading WEBVTT, then the same index, then the same timing line with a period instead of a comma, then the same text. The header and the separator are marked as the only two differences. One cue, written twice Same index, same 12-character stamps, same words. Two characters of difference. transcript.srt 1 00:00:01,234 --> 00:00:03,900 the words starts on the index line transcript.vtt WEBVTT 1 00:00:01.234 --> 00:00:03.900 the words one line earlier, always difference 1 the WEBVTT line and the blank line under it difference 2 a comma or a period before the milliseconds not a difference index, stamp length, cue order, words
The two files are the same list of cues with two characters changed. The right-hand file carries an 8-byte header that the left-hand file does not have — that header is the entire size difference between 3,599 bytes and 3,591 bytes. The comma and the period sit in the same position of a 12-character stamp, so they cost nothing. Everything else — the index, the two stamps, the line of words — is identical, which is why a .srt renamed to .vtt still contains no header and a .vtt renamed to .srt still does.

Which one goes where

The decision is about the reader, not the file. A person imports an SRT into an editor or drops it into a caption upload box; a browser loads a VTT through the <track> element, and WebVTT is the only text track format browsers implement. That single split accounts for nearly every request you will meet, and it is why the fallback is SRT: more things read it.

Two subtitle files on the left and the two readers that accept them on the right. The .srt reaches the editor along a solid line; the .vtt reaches the browser track element along a solid line; a dashed red line from the .srt to the track element is crossed out, because that pairing produces no cues and no error message. Two files, two readers, one silent mismatch The header decides who can read the file, and a wrong pairing says nothing at all. the file .srt no header line at all stamp uses a comma .vtt opens with WEBVTT, blank line stamp uses a period the reader an editor or upload box takes a timing line ignores an unknown header a browser track element requires WebVTT shows nothing without it The dashed line is the one that fails quietly: no cues, no console error, nothing to debug. Renaming a file does not move it across this diagram, because the header travels with the bytes.
Which file to hand to which program, and the one pairing that fails without saying so. The two files are the same list of cues: 100 cues of one character each come out of the deployed writers as 3,591 bytes of .srt and 3,599 bytes of .vtt, and the 8 bytes between them are the string WEBVTT and a blank line. The comma and the period sit in the same position of a 12-character stamp, so they change a byte without changing a length. The dashed red line is a .srt given to a <track> element: the player renders nothing and the console stays empty, which is why renaming a file never fixes this — the header has to be written, and only one of the two writers writes it.

What this tool actually writes, line by line

Everything below was read from the deployed app.js — 22,349 bytes, the same file the page you are on loads — or measured by calling its functions on this machine. None of it is a description of the formats in general; it is what comes out of the two download buttons.

What the three pages that outrank this one say about the choice

Across the 10 Instagram pages the three sites publish — 111,520 characters of body text once the heading lists and the scraper’s metadata are stripped, because a reader never sees those — the two format names appear 10 times in total. Not one of those mentions explains when to use which, and the phrase “difference between” appears 0 times in the 226,947 characters of the whole benchmark corpus.

How to tell which file you are holding

Three checks, each a few seconds, and they settle it without opening any software: the first line, the character before the milliseconds, and the size. All three work on a file you downloaded weeks ago and cannot remember the source of.

Can I feed a .vtt to a program that asks for .srt?

Only if that program parses WebVTT, and most importers that ask for .srt do not. The failure is not a warning: the header line sits where the first cue index should be, so the parser either drops cue one or rejects the file. Convert it by deleting the 8-byte header, swapping periods for commas and unescaping the entities — or simply export the 3,591-byte .srt instead of the 3,599-byte .vtt, which is one click and no editing.

Why is the file so much bigger than the text I copied?

Because the words are the small part. 100 cues of one character occupy 3,591 bytes, of which 3,392 are scaffolding — 3,200 fixed bytes plus 192 of index digits — and the remaining 199 bytes are the characters and the blank lines between blocks. Add real sentences and the text share rises; at 50 characters a cue the same 100 cues come to 8,491 bytes, so the structure is still a third of the file.

Does the timestamped transcript download as SRT or VTT?

Both, and both carry the same stamp. The timestamped view on screen and the two subtitle files are three renderings of one set of cues: the screen shows the 12-character stamp in front of each line, and buildSrt() and buildVtt() write the same 12 characters with a comma or a period, producing 3,591 bytes and 3,599 bytes from the same 100 cues. There is no third file format hiding behind the timestamped view.

Why did the download button give me an error instead of a file?

Because no cue survived the duration filter. subtitleCues() drops every cue whose end is not after its start, and if all of them go, the button reports “This run produced no cue with a real duration, so there is no subtitle file to make.” instead of writing something. A 0-byte download never happens: either you get a file with at least one cue or you get that message, and the words themselves are still in the panel to copy.

Which format carries speaker labels?

Neither, and that is a property of the cues rather than of the container. A cue in this tool has three fields — start, end and text — and 0 of them names a voice, so both the 3,591-byte .srt and the 3,599-byte .vtt come out with no label at the front of any line. Separating speakers is a different problem with different routes.

Is the .srt always smaller?

Yes, and by a fixed 8 bytes plus 4 for every escaped character. The header is the only structural difference, so 3,591 against 3,599 stays 3,591 against 3,599 no matter how long the transcript is; the gap only widens when the text contains ampersands, angle brackets or the arrow sequence that VTT has to neutralise. Size is not a reason to choose between them at any length you will meet on Instagram.

Last checked: 26 October 2026. The byte figures were produced on this machine by extracting stamp(), vttText(), buildSrt() and buildVtt() from the deployed app.js and running them on generated cues: 100 cues of one character gave 3,591 bytes as .srt and 3,599 bytes as .vtt, 40 cues gave 1,430 and 1,438, one cue of two characters gave 35 bytes, a cue reading R&D gave 36 and 48, and 100 cues of 50 characters gave 8,491. The 4 chunks that became 3 segments and 2 cues came from running toSegments() and subtitleCues() together on a hand-built input holding one empty-text chunk and one zero-length cue. The 3,392 bytes of scaffolding is 3,200 fixed bytes plus 192 index digits, counted from the same output; the 12-character stamp length was read off the pad() calls at line 351 and confirmed on a cue at 3,600 seconds. The source facts — 22,349 bytes of app.js, subtitleCues() at line 365, the three replacements at line 377, the two builders at lines 382 and 385, the hardcoded transcript.${kind} at line 520 and the text/plain;charset=utf-8 Blob at line 536 — were read from the deployed file, not from memory. The competitor figures cover 10 Instagram pages and 111,520 characters of body text, and 226,947 characters across the 33 files in this site’s benchmark directory, measured after the heading lists were stripped; the sentences quoted from getthescript.app, speakapp.com and wayin.ai are reproduced exactly as they appear there. Which programs import .srt is general knowledge about those editors rather than something measured here; the claim that a browser track element takes only WebVTT is from the HTML specification.

If the words are still inside the video, a video with no captions covers why a missing caption track changes nothing here, and the timestamps page covers what the 12 characters in front of every line are made of. Who said what explains why neither subtitle file can label a speaker, what to do with a transcript covers the downstream uses of both files, and Instagram’s own captions covers the route that never produces a file at all. The 3,840,000 bytes of audio behind a one-minute cue list are worked out on the upload page, next to the 79.7 MB model that decodes them.