Found me on Upwork? If you found me through Upwork and want to work together, please contact me through Upwork. Messages from Upwork clients sent outside Upwork will not be answered.
Comparison🎬 Captioning & Subtitles

Burned-in vs Soft Captions for Social Video: Which to Use?

Burned-in or soft captions for social: TikTok and Reels need burn-in, YouTube uploads SRT. ffmpeg commands for both with exact force_style and mov_text flags.

Dao Huy (Lucas)7 min read8 sections · side-by-side table
Burned-in vs Soft Captions for Social Video: Which to Use?

💡 For social video, the platform determines which method to use. TikTok and Instagram Reels do not accept external subtitle files, so burned-in captions are the only way to deliver styled text on these platforms. YouTube and YouTube Shorts accept SRT uploads directly, making a soft caption track the better choice there: no re-encode, viewer-toggleable, and reusable for translation.

Key takeaways

  • Burned-in: -vf "subtitles=captions.srt:force_style='FontName=Arial,FontSize=28,Outline=2,MarginV=160'" plus a video re-encode with -c:v libx264 -crf 23. Text becomes permanent pixels.
  • Soft track (MP4): -c:s mov_text -metadata:s:s:0 language=eng -disposition:s:0 default. Video and audio copy with -c:v copy -c:a copy: no re-encode, no quality loss.
  • TikTok and Instagram Reels: no subtitle file upload slot. Burned-in is the only way to deliver styled, precisely positioned captions before upload.
  • YouTube and YouTube Shorts: upload SRT or VTT directly in YouTube Studio. No video re-export needed; viewers can toggle the track on or off.
  • Burned-in captions cannot satisfy WCAG 1.2.2 for web video (they cannot be toggled). A soft track is required for accessibility compliance.

What is the difference between burned-in and soft captions?

Burned-in captions (also called hardcoded or open captions) are rendered into the video frame itself: every pixel of text becomes part of the image permanently. Once encoded, you cannot remove or reposition them. A re-encode is unavoidable because the subtitles filter runs inside ffmpeg's video filter graph, which requires the video to be decoded, filtered, and re-compressed.

Soft captions sit in a separate track inside the container. The player renders them at runtime. The video stream is never touched: -c:v copy passes it through byte-for-byte. I use soft tracks for anything that will need editing, multiple languages, or viewer control.

FactorBurned-inSoft track
Viewer can toggleNoYes (player caption menu)
Video re-encode neededYesNo (-c:v copy)
Editable after deliveryNoYes (replace the file)
Multi-language outputOne re-encode per languageMultiple tracks, one file
WCAG 1.2.2 (web accessibility)Fails (cannot be toggled)Meets toggle requirement

Which social platforms accept a subtitle file upload?

This is the decision point that determines everything else. YouTube is the exception that makes soft tracks practical for creators. TikTok and Reels are the reason burn-in exists as a creator workflow.

PlatformSRT uploadVTT uploadAuto-captionsIn-app edit
YouTube / ShortsYesYesYesYes (YouTube Studio)
TikTokNoNoYesYes (after auto-gen)
Instagram ReelsNoNoYesYes (Edits app)

YouTube also accepts SBV, SCC, TTML and several other formats. For a creator delivering a translated subtitle track, SRT is the simplest choice: plain text, editable in any editor, accepted everywhere YouTube accepts subtitle files.

TikTok and Instagram generate auto-captions from audio on upload and allow in-app text editing. Neither platform exposes an upload slot for an external subtitle file. If the auto-generated text is inaccurate or you need a translated track, your options are: edit in-app (limited and time-consuming), or burn a corrected version into the video pixels before upload.

How do I burn captions into a video with ffmpeg?

The subtitles filter renders SRT, WebVTT, or any libass-supported format. The force_style option overrides the default libass appearance using ASS V4+ field names. Here is the command I use for a vertical 1080x1920 short-form video destined for TikTok or Reels:

ffmpeg -i input.mp4 \
  -vf "subtitles=captions.srt:force_style='FontName=Arial,FontSize=28,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BorderStyle=1,Outline=2,Shadow=0,MarginV=160'" \
  -c:v libx264 -crf 23 -preset slow \
  -pix_fmt yuv420p \
  -c:a copy \
  burned_output.mp4

Key flags:

  • force_style='...': overrides the libass default style. ASS colour values use ABGR byte order: white is &H00FFFFFF, solid black outline is &H00000000. Alpha byte 00 = fully opaque.
  • MarginV=160: pixels from the bottom edge of the 1080x1920 frame. I keep this at 160 on vertical video to stay clear of TikTok and Reels bottom UI overlays. Adjust if the platform changes its chrome height.
  • -c:v libx264 -crf 23 -preset slow: H.264 encode at CRF 23 with the slow preset for better compression. Use -crf 18 for higher-quality deliverables.
  • -pix_fmt yuv420p: forces 4:2:0 chroma subsampling. Some ffmpeg builds produce yuv420p10 when libass renders; platforms re-encode that with a second chroma conversion, adding blur to the text.
  • -c:a copy: the subtitle filter does not touch audio. Copy it through unchanged.

How do I add a soft caption track without re-encoding?

For MP4 output, the only accepted text subtitle codec is mov_text (3GPP Timed Text). Using -c:s srt or -c:s copy into an MP4 container causes an error or writes a track most players silently ignore. For YouTube, I produce the MP4 first, then upload the .srt separately - no re-encode at any step.

ffmpeg -i video.mp4 -i captions.srt \
  -map 0 -map 1 \
  -c:v copy -c:a copy \
  -c:s mov_text \
  -metadata:s:s:0 language=eng \
  -metadata:s:s:0 title="English" \
  -disposition:s:0 default \
  soft_output.mp4

What each flag does:

  • -map 0 -map 1: include all streams from the video input, plus the first stream from the SRT input.
  • -c:v copy -c:a copy: pass video and audio through byte-for-byte. No quality loss, almost no processing time.
  • -c:s mov_text: convert the SRT to 3GPP Timed Text, the only text subtitle codec MP4 supports.
  • -metadata:s:s:0 language=eng: ISO 639-2 language tag. Use vie for Vietnamese, fra for French.
  • -disposition:s:0 default: pre-selects this track in players that auto-load a subtitle stream.

Verify the result: ffprobe -v error -select_streams s -show_entries stream=codec_name:stream_tags=language -of default=noprint_wrappers=1 soft_output.mp4. If codec_name is not mov_text, most players will skip the track silently.

Should I combine both methods on the same file?

I do this when a client needs both platform coverage and viewer control. The workflow: start from the same source video and SRT, produce a burned-in MP4 for TikTok and Reels, and produce a separate clean MP4 with a soft track for YouTube. Both outputs share the same timing and text: no translation or re-timing divergence between them.

The scenario where combining pays off most is a translated subtitle track. Burn the Vietnamese version into the TikTok copy (since TikTok cannot accept a sidecar file). Embed a Vietnamese soft track in the YouTube copy alongside an English track. One SRT per language, two delivery variants, no re-translation needed.

What you can do yourself vs where a specialist helps

Both commands above are fully self-service. Write the SRT, burn it for TikTok and Reels, upload the SRT to YouTube Studio. For single-language content with clean speech, that covers the full technical workflow.

The calculation shifts for translated subtitles. Vietnamese translated from English regularly overflows reading-speed limits because Vietnamese lines are longer than their English source. A machine-translated .srt timed to English cues often runs too fast to read comfortably. I translate in Subtitle Edit with the CPS (characters per second) warning live on screen, adjusting line breaks until every event stays inside the reading-speed limit before the file goes to ffmpeg.

For branded video series, multi-language delivery, or web video that must meet a style guide, professional timing and native-language QC earns its cost. My vertical subtitle service covers both the burn-in and the soft-track delivery path, from translation through ffmpeg export.

FAQ

Can I burn in captions without re-encoding the video?

No. The subtitles and ass filters run inside ffmpeg's video filter graph, which requires decoding and re-encoding the video stream. Using -c:v copy while a -vf filter is active causes an error. Audio is unaffected: -c:a copy always works alongside a subtitle filter.

Why do my burned-in captions look blurry after TikTok upload?

TikTok re-encodes every upload. If captions were rendered onto a scaled-down proxy before the final H.264 encode, the re-encode compounds the blur. Always burn onto the full 1080x1920 frame. Also include -pix_fmt yuv420p: some ffmpeg builds produce yuv420p10 when libass renders, and TikTok's pipeline converts that with a second chroma pass.

Can I upload Vietnamese subtitles to YouTube as a soft track?

Yes. Upload the Vietnamese .srt in YouTube Studio and select Vietnamese as the language. The viewer can choose it from the caption menu alongside any other tracks. Save the file as UTF-8 without BOM from Subtitle Edit: Vietnamese precomposed characters with diacritics are within UTF-8 and render correctly in YouTube's player.

Does mov_text preserve Vietnamese diacritics in an MP4?

Yes, as long as the source SRT is UTF-8 encoded. The mov_text codec stores text in UTF-8 inside the MP4 container. The common failure mode is a source file saved in Windows-1252: diacritics are garbled before ffmpeg processes the text. Check File > Character encoding in Subtitle Edit and re-save as UTF-8 without BOM before running the ffmpeg command.

What is the right CRF for burning captions into a social video?

For TikTok and Reels, I use -crf 23: it produces a clean file at a manageable size and the platforms re-encode on their end anyway. For a YouTube upload where the platform preserves more of the original quality, I prefer -crf 18 to keep the burned text sharp after the platform's processing. Both use -preset slow for better compression at the same quality level.

Official Sources

Dao Huy (Lucas)
Dao Huy (Lucas)
Graduate, University of Foreign Language Studies, University of Da Nang. Signs a certificate of accuracy on every certified translation (USCIS, IRCC).

Written by Dao Huy (Lucas), Vietnamese translator and localization specialist (English, Chinese and French into Vietnamese). See translation services →

Get QuoteWhatsApp