Extract ATSC Closed Captions to SRT with FFmpeg
This guide explains how to extract ATSC broadcast closed captions
(typically EIA-608 or CEA-708) from an MPEG-2 Transport Stream
(.ts) and convert them into a standalone SubRip
(.srt) subtitle file using FFmpeg. You will learn how to
identify the caption data embedded within the transport stream, map the
correct subtitle or video stream, and apply the appropriate conversion
commands to generate a properly synchronized subtitle file.
Step 1: Inspect the Transport Stream
ATSC closed captions are often multiplexed directly into the MPEG-2
or H.264 video stream as user data, or they may appear as a distinct
subtitle stream. Run ffprobe to determine how FFmpeg
recognizes the streams in your file:
ffprobe -hide_banner input.tsCheck the output for subtitle streams. If FFmpeg recognizes the closed captions directly, you will see an entry such as:
Stream #0:2[0x102]: Subtitle: eia_608 (bin_data)
Step 2: Direct Subtitle Extraction
If ffprobe lists an active subtitle stream (such as
eia_608 or cea_708), extract it directly to an
SRT file using the following command:
ffmpeg -fix_sub_duration -i input.ts -map 0:s:0 -c:s srt output.srt-fix_sub_duration: Resolves missing or overlapping subtitle durations common in broadcast television streams.-map 0:s:0: Targets the first detected subtitle stream in the first input file. Adjust the index if multiple caption tracks exist.-c:s srt: Encodes the extracted caption track into the SubRip format.
Step 3: Extracting Captions Embedded in Video Frames
If the closed captions are not automatically exposed as an
independent subtitle track, they are embedded directly into the video
stream frames. Use the subcc filter via the
lavfi virtual device to decode the embedded closed
captions:
ffmpeg -f lavfi -i "movie=input.ts[out0+subcc]" -map 0:s:0 -c:s srt output.srtAlternatively, you can read the video track directly and instruct FFmpeg to output the closed caption channel:
ffmpeg -i input.ts -map 0:v:0 -c:s srt output.srtStep 4: Selecting Specific Closed Caption Channels
Broadcast streams frequently carry multiple CC channels (e.g., CC1
for primary audio, CC2/CC3 for secondary audio or Spanish translations).
When multiple streams are present, use the -map option with
the corresponding stream identifier found in your ffprobe
output:
ffmpeg -fix_sub_duration -i input.ts -map 0:s:1 -c:s srt output_spanish.srtThis ensures only the desired channel is extracted and converted into
the final .srt output.