Burn subtitles permanently into the picture. SubRip, WebVTT and Advanced SubStation all read, every cue listed with the exact frames it covers, and the styling set as a percentage of the frame.
Initializing in your browser…
Cut a clip out of a video, choosing whether the cut lands on the exact frame (re-encodes to MP4) or leaves the streams untouched (instant and lossless, but only at a keyframe). The result says which ran and reads the real length back off the file.
Convert a video between MP4, WebM, OGG, MOV, AVI and MKV, each naming the codecs it really writes and each producing a file that actually plays. One quality dial normalised into four different encoder scales.
Join clips end to end, saying in advance whether they can be stitched together untouched and, when they cannot, exactly which differences stop it. Clips of different sizes are letterboxed into one frame rather than squashed.
Social videos need captions hardcoded because most viewers watch muted and platforms ignore sidecar files.
Input
reel.mp4 + captions.vtt · 5% of the frame height, bottom, outlined
Output
reel.mp4 with each cue on exactly the frames its timecode names
A cue from 0.200 to 0.700 seconds on a 30 fps source covers frames 6 to 21, and the page lists that range for every cue before it runs. WebVTT is genuinely read here, including timestamps written without an hours field, which is legal and which a SubRip-only reader loses silently: a three cue WebVTT file used to come out with two captions burned in and no warning at all.
Burn subtitles permanently into your video so they display on any player without a separate file. SubRip, WebVTT and Advanced SubStation are all read, every cue is listed with the exact frames it covers, and the styling is set as a percentage of the frame so it reads the same at any resolution.
Burn subtitles into videos for Instagram, TikTok, and Facebook where many viewers watch without sound.
Ensure deaf and hard-of-hearing viewers can always see captions, regardless of the player or platform.
Permanently embed translated subtitles into videos for audiences who do not speak the original language.
Load a WebVTT or Advanced SubStation file and save the cues back out as a clean SubRip file, with the markup already removed.
Which frames a caption covers is arithmetic rather than a matter of opinion. A frame is presented at its index divided by the frame rate and the enable window is inclusive at both ends, so a cue from 0.200 to 0.700 seconds on a 30 fps source covers frames 6 to 21 and nothing else. The page lists every cue with the frames it will occupy, and that list is what the burn produces.
The formats are where the trouble was. SubRip writes its timestamps with a COMMA before the milliseconds. WebVTT writes a full stop and may leave the hours off entirely, which is legal and common. Advanced SubStation writes its cues on Dialogue lines with hundredths rather than thousandths. A reader that only knows SubRip loses every WebVTT cue written without an hours field, silently: a three cue WebVTT file used to come out with two captions burned in and no warning at all, and an Advanced SubStation file always failed outright even though the file picker accepted one. All three are read now, into one list of cues, and the page says which format it recognised and how many cues it found. Formatting tags are removed rather than drawn, and the page says how many cues carried them, because a burned caption is one font at one weight.
Line breaking is measured rather than counted. Text is wrapped by measuring it in the font it will be drawn in at the size it will be drawn at, against a real fraction of the frame width. The previous rule was a character count against a hardcoded 850 pixel guess at the video's width, which on a 640 wide frame at a large size allowed lines exactly as wide as the picture. Type size is set as a percentage of the frame height, so a caption is the same apparent size on a phone clip and a master, and the pixel figure is shown beside it.
Overlapping cues are legal in SubRip and common in real files. Two of them at the same position draw on top of each other, so each cue is given a row of its own and the page says how many rows the busiest moment needs. Every cue is written to its own file and drawn from it, which means nothing in a subtitle file can be read as filter syntax and a caption containing a percent sign is drawn rather than silently dropped. The chain was measured rather than feared: ten cues cost 189 ms and four hundred cost 267, because only the cues on screen at a given moment do any work.
One thing this build cannot do, stated because it is the obvious question. The encoder here is compiled with libass, the renderer VLC and mpv use for subtitles, and its subtitles filter parses a file perfectly and then draws nothing at all: its default style names Arial, a WebAssembly build has no fontconfig to substitute anything, and pointing it at a directory containing a font did not change it. So captions are drawn one at a time with the bundled Roboto instead.
No. Once subtitles are burned into the video frames, they cannot be removed. Always keep a copy of the original video.
All three. WebVTT timestamps use a full stop and may leave off the hours, and Advanced SubStation puts its cues on Dialogue lines with hundredths; both are read into the same list of cues. Only the words and the timings are taken from an ASS file: its own fonts, colours and positions are not applied, and the page says so.
Each gets its own row, so both are readable. Overlapping cues are legal and common, and drawing them at the same position puts one on top of the other.
If the video resolution is low, text will not render sharply at any size. Try raising the type size, which is a percentage of the frame height here, and adding an outline or a background box for contrast.
One at a time. To add a second language, burn the first, then use the output as the input and burn the second at a different position.
Video is decoded and re-encoded on your own device. Large files never leave your machine.