Subtitle Soft-Embed Tool
Add toggleable subtitle tracks inside a video container. The video and audio aren't re-encoded, so the mux completes in seconds. Pick MP4, MKV, or WebM.
- In your browser
- Files never uploaded
- Free
Frequently asked questions
How is this different from the Burn-In tool?
Burn-in renders the subtitles into the video pixels — they're always visible and can't be turned off. Soft-embed adds the subtitles as a separate, toggleable track inside the container, so the viewer can switch languages or hide captions in any decent player. Soft-embed produces both an MP4 (universal) and a WebM (preserves subtitle styling) from a single run. Use burn-in when delivering a finished video where viewers should not need to enable anything. Use soft-embed when delivering content with multi-language options or when you need the subtitle text to stay editable inside the file.
Why two outputs (MP4 + WebM)?
They serve different needs. MP4 with mov_text plays everywhere (iOS, QuickTime, smart TVs, every desktop player) but the codec is plain-text only — any styling carried in your source files (font weight, color, italic, bold) is stripped. WebM with WebVTT preserves that styling and is the format your post-embed preview uses, so you can verify visually that the captions look right before you ship. Pick MP4 when compatibility is the priority; pick WebM when styling is the priority.
Why does the WebM output sometimes take much longer than the MP4?
WebM strictly requires VP8/VP9 video plus Opus or Vorbis audio. If your source already uses those codecs (e.g. it's already a .webm file), the WebM mux is fast — just a copy. If your source is H.264/AAC (most common), we have to re-encode the video to VP8 and the audio to Opus, which is significantly slower in WebAssembly than a copy mux. The MP4 download is unaffected and still finishes quickly.
Why is my WebM output downscaled to 720p when my source is 1080p / 4K?
WebAssembly has a per-page linear-memory ceiling (around 2-4 GB depending on the build), and VP8 encoding at full 1080p or 4K easily blows past it — the run aborts with "memory access out of bounds" partway through. To make the WebM output reliable on real-world sources, we cap it at 1280px wide (≈720p for 16:9 video). Sources already at or below that resolution pass through unchanged. The MP4 download is NOT downscaled — it preserves your original video pixels exactly, byte-for-byte.
Will the new subtitle track be the default in the downloaded file?
Yes — we explicitly mark one new track (whichever you flagged "Default" in the UI, or the first one if you didn't flag any) with the container's default disposition. Most desktop players (VLC, mpv) and many smart-TV apps auto-display the default track on play. Caveat: when you turn on "Keep existing subtitle tracks", the source video's existing subs stay in the output and may take precedence in some players — soft-embed can't reorder source tracks without a separate probe pass. Browsers' built-in <video> elements ignore embedded-track default flags entirely and require manual CC enable; that's a browser limitation, not a file limitation.
Why does my MP4 lose subtitle styling like font size or color?
The MP4 container uses the mov_text subtitle codec, which is plain-text by spec — there's no place in the format for font size, color, position, or other styling. This is a format limitation, not something we can change. If you need styling preserved, use the WebM download (its WebVTT codec carries CSS-style cue settings) or use the Burn-In tool to render the styled subtitles directly into the video pixels (where they'll play anywhere, on any player).
Does my video get uploaded to a server?
No. The video is mounted into FFmpeg's in-browser virtual filesystem via WORKERFS — FFmpeg reads it lazily from your local file handle without copying it into JS memory. Subtitle parsing and both mux passes happen entirely in the browser. Nothing leaves the page.
How many subtitle tracks can I add?
As many as you want. Each track gets its own language code, display title (e.g. "한국어" or "English (forced)"), and a "default" toggle that tells the player which track to show first. Some players (notably YouTube's desktop player and a few smart-TV apps) will only show the first 4-5 tracks; everything stays in the file regardless.
Will the existing subtitle tracks in my video be kept?
No — by default we strip every existing subtitle track and replace them with the new ones you provide. This keeps the output predictable. There's a checkbox to keep existing tracks if you need them; otherwise run the tool twice and chain the outputs.
Which subtitle formats can I drop in?
SRT, VTT, ASS, SSA, SMI, TTML, DFXP, SBV, LRC, MicroDVD, and SubViewer. They're normalized to mov_text for the MP4 output (plain text) and to WebVTT for the WebM output (basic styling preserved). ASS karaoke / transform tags are not preserved in either output — for those, use the burn-in tool, which renders ASS effects natively via libass.
My player won't show the subtitles — what do I do?
Toggle them on in the player's subtitle / caption menu — soft-embedded tracks are off by default in some apps. If you're using the MP4 download, confirm your player supports mov_text (VLC and modern phones do; some older smart TVs don't). If still no luck, try the WebM download or the burn-in tool — burn-in bakes the captions into the pixels so no player toggle is required.
