Extract Closed Captions from ATSC to SRT Using FFmpeg

Extracting closed captions from an ATSC transport stream (.ts file) is a highly efficient way to generate standalone subtitle files for archiving, editing, or media player compatibility. This guide provides a direct, step-by-step method to identify, extract, and convert embedded EIA-608 or CEA-708 closed captions from an ATSC video file into a standard SubRip (.srt) format using the FFmpeg command-line tool.

Step 1: Identify the Closed Caption Stream

ATSC transport streams often contain multiple audio, video, and subtitle tracks. Before extracting, you need to locate the specific index of the closed caption track.

Run the following command in your terminal to inspect the file:

ffmpeg -i input.ts

Scan the output for lines labeled Subtitle. You will typically see an entry resembling this:

Stream #0:3[0x1c1]: Subtitle: eia_608 (c608 / 0x38303663), 90000 tbr

In this example, the closed caption track is recognized as eia_608 (the standard for North American analog television closed captions, often embedded in digital ATSC streams) and is located at stream index 0:3 (or the first subtitle stream, s:0).

Step 2: Extract the Caption Track to SRT

Once you have identified the stream, you can extract it. Use the -map flag to select the subtitle stream and specify .srt as the output format.

To extract the first subtitle stream found in the file, run:

ffmpeg -i input.ts -map 0:s:0 output.srt

ATSC closed captions often lack explicit duration markers, which can result in subtitles that overlap or stay on screen too long. You can resolve this by adding the -fix_sub_duration flag:

ffmpeg -fix_sub_duration -i input.ts -map 0:s:0 output.srt

This flag forces FFmpeg to calculate the duration of each subtitle line based on when the next line of text appears, ensuring clean timing in your final SRT file.

Troubleshooting: Selecting Specific Channels (CC1, CC2)

If your ATSC stream contains multiple caption channels (such as English on CC1 and Spanish on CC2) and FFmpeg detects them as separate streams, you can map them individually.

To extract the second subtitle stream (CC2), change the map index:

ffmpeg -fix_sub_duration -i input.ts -map 0:s:1 spanish_output.srt