Map Closed Captions with FFmpeg copyts
This article explains how to successfully map and preserve closed
caption streams when copying video and audio codecs using the
-copyts option in FFmpeg. By default, FFmpeg may discard
subtitle or data streams containing closed captions during stream
copying unless they are explicitly mapped, which can lead to
desynchronization or missing captions.
When copying codecs (-c copy) while preserving original
presentation timestamps (-copyts), you must use the
-map option to instruct FFmpeg to include the closed
caption streams. Captions are typically stored either as embedded data
within the video stream (such as CEA-608/708 in H.264 SEI user data) or
as a separate subtitle/data stream.
The FFmpeg Command Syntax
To copy all video, audio, and subtitle/caption streams while preserving timestamps, use the following command structure:
ffmpeg -copyts -i input.mp4 -map 0:v -map 0:a -map 0:s? -c copy output.mp4Key Options Explained
-copyts: Instructs FFmpeg to preserve the input presentation timestamps (PTS) instead of resetting them to start at zero. This is crucial for maintaining synchronization with captions that rely on absolute source timestamps.-map 0:vand-map 0:a: Explicitly maps all video and audio streams from the first input file.-map 0:s?: Maps all subtitle streams (which often contain closed captions). The trailing?is a helper flag that prevents FFmpeg from failing if the input file does not contain any subtitle streams.-c copy: Enables stream copying (codec copy) for all mapped streams, bypassing the decoding and re-encoding process to save CPU resources and preserve original quality.
Handling Embedded Captions (CEA-608 / CEA-708)
If your closed captions are embedded directly inside the video stream
(as is common with ATSC broadcasts or MPEG-TS files), they are part of
the video bitstream payload. Running -c:v copy with
-copyts will automatically copy these embedded captions
without requiring a separate subtitle map, as long as the video stream
itself is mapped (-map 0:v).
However, if the captions are exposed as a separate data stream (often
labeled as data or bin in FFmpeg’s stream
output), you must map the data stream explicitly using the
-map 0:d? option:
ffmpeg -copyts -i input.ts -map 0:v -map 0:a -map 0:d? -c copy output.tsUsing these mapping techniques ensures your closed captions remain
perfectly synchronized and intact when utilizing the
-copyts flag.