Convert SRT to Broadcast-Safe SCC (CEA-608) and Verify the Decode
← 博客
🎬 字幕与隐藏字幕7 min read

Convert SRT to Broadcast-Safe SCC (CEA-608) and Verify the Decode

💡 To produce a broadcast-ready SCC (CEA-608) file from an SRT: run seconv in.srt ScenaristClosedCaptionsDropFrame --fps:29.97 --output-folder:out --overwrite, then QC the result with caption-inspector. CEA-608 caps at 32 characters per row and 15 rows, requires drop-frame timecode (semicolons) for 29.97 fps, and supports only the Latin character set - so English captions go in the SCC; any other language travels as a separate subtitle track.

Key takeaways

  • Conversion command: seconv in.srt ScenaristClosedCaptionsDropFrame --fps:29.97 --output-folder:out --overwrite
  • CEA-608 grid: 32 characters per row maximum, 15 addressable rows on screen
  • 29.97 fps requires drop-frame timecode - semicolons: 00:00:01;15, not colons 00:00:01:15
  • CEA-608 is Latin-only. Non-Latin scripts are silently dropped or garbled by 608 encoders.
  • Verify every SCC with caption-inspector before submitting to a broadcaster or platform

What makes an SCC file different from SRT for broadcast?

An SRT file is plain text with millisecond timestamps - it has no concept of a TV field or a frame. An SCC (Scenarist Closed Captions) file stores CEA-608 closed-caption data as hex byte pairs on SMPTE 29.97-fps drop-frame timecodes. US broadcasters and streaming platforms that require closed captions under FCC rules do not accept SRT for their caption tracks - they need an SCC, or a 708-service format like SMPTE-TT/ST 2052-1 for HD workflows.

The SCC encodes more than text. It carries CEA-608 control codes: which row to display on, pop-on or roll-up mode, the erase-memory signal that clears a caption from the screen. A converter that handles those codes incorrectly produces a file that parses without errors but displays wrong text or wrong timing on a real decoder. That is why I always run a decode check after converting.

One constraint worth naming clearly: CEA-608 is an English/North American broadcast standard. Its character set covers the EIA-608 Latin table - English and limited Western European characters. Non-Latin scripts such as Chinese, Japanese, Korean, or Arabic cannot be encoded in a 608 track. Other languages are delivered as separate subtitle tracks (SRT or IMSC), not as 608 data. This is the CEA-608 specification itself, not a tooling limitation.

The CEA-608 constraints your SRT must fit within

Before converting, I audit the SRT against the 608 grid. Lines that exceed 32 characters get truncated or wrapped unpredictably. More than four visible lines in a single caption event can cause display overlap on some decoders.

CEA-608 featureValue / limit
Max characters per row32
Addressable rows on screen15 (rows 1-15)
Max visible rows in one pop-on event4
Roll-up modes availableRU2 (2 rows), RU3 (3 rows), RU4 (4 rows)
Character encodingEIA-608 Latin table (no CJK, no Arabic)
Timecode format at 29.97 fpsDrop-frame: HH:MM:SS;FF
Timecode format at 30 fps NDFNon-drop: HH:MM:SS:FF
Primary caption channel (English)CC1 (Field 1, channel 1)

I check character counts in Subtitle Edit: View > Show character count per line. Any line over 32 characters gets split before I run seconv. Subtitle Edit's Fix common errors can automate splits on a consistent source file, but for broadcast deliverables I do a manual pass to control line-break placement.

How do I run the SRT to SCC conversion with SeConv?

I use SeConv - the command-line interface of Subtitle Edit - for this conversion. It handles the CEA-608 byte encoding and the frame-number remapping from milliseconds to SMPTE timecode correctly.

# Convert one SRT to drop-frame SCC at 29.97 fps
seconv.exe in.srt ScenaristClosedCaptionsDropFrame --fps:29.97 --output-folder:out --overwrite

# Batch convert an entire folder
seconv.exe *.srt ScenaristClosedCaptionsDropFrame --fps:29.97 --output-folder:out --overwrite

What each argument does:

  • in.srt - the source file (or a glob pattern like *.srt for batch conversion)
  • ScenaristClosedCaptionsDropFrame - the SeConv format name for 29.97 drop-frame SCC. For a 30 fps non-drop-frame master, use ScenaristClosedCaptions instead.
  • --fps:29.97 - the target frame rate; governs how millisecond timestamps map to frame numbers in the SCC output. NTSC broadcast is almost always 29.97.
  • --output-folder:out - destination folder for the .scc file
  • --overwrite - replace any existing output file with the same name

Open the output .scc in a text editor and do a quick sanity check: the file must start with Scenarist_SCC V1.0, and every timecode must use semicolons (00:00:01;00). Colons in a 29.97 output mean the non-drop-frame format was used by mistake.

How do I verify the SCC decodes correctly?

A valid SCC file is not the same as a correct SCC file. A conversion that produces valid hex pairs can still have mis-ordered control codes that cause a decoder to display wrong text or skip a caption. My decode check uses caption-inspector - a free, open-source tool from Comcast, run as a Docker container:

# QC-decode an SCC file with caption-inspector
docker run --rm -v /path/to/captions:/data   nebulabroadcast/caption-inspector   -o /data /data/in.scc

This writes three output files into the same directory:

  • in-C1.608 - a plain-text decode of the CEA-608 stream: the caption text and control codes exactly as a real decoder would see them. This is the file I read to verify the text is complete and correct.
  • in-S1.708 - the CEA-708 service layer (shows minimal data for an SCC-only file, since SCC carries only 608)
  • in.ccd - character-level byte detail for debugging encoding anomalies

In the -C1.608 output I look for: truncated words, missing caption events, garbled characters (indicating a character outside the 608 Latin table), and control codes in the wrong order. If the text reads cleanly and timing looks right, the SCC is ready to deliver.

What should I fix in my SRT before converting?

A few issues come up consistently when I convert SRTs not originally written for 608 delivery:

  • Lines over 32 characters - split them. The encoder will truncate or wrap silently, no warning from SeConv.
  • Non-Latin text - the CEA-608 encoder drops or garbles any character outside its Latin table. Remove or replace those characters before converting. There is no error message.
  • More than 4 lines in one event - split the event into two with a small gap between them.
  • Overlapping timecodes or zero-duration events - use Subtitle Edit's Fix common errors to clean these up first. A broadcaster's QC system will reject them.
  • HTML formatting tags - <b>, <i>, <u> convert to CEA-608 formatting codes. Check that every tag is properly closed in each event before converting.

When is a conversion enough, and when do I need a full caption pass?

A seconv conversion from a properly-written SRT produces a technically valid SCC. But FCC closed-captioning quality standards require more than a valid file format. The FCC benchmarks - accuracy, synchronicity, completeness, and placement - are about the captions reflecting what was actually said and heard, including sound effects, music cues, and speaker identification for programs with multiple voices.

My dividing line: if the original SRT was written as a closed-caption file (it includes hearing-impaired sound cues like [DOOR SLAMS], speaker IDs, music notation), a seconv conversion to SCC is broadcast-safe. If the SRT was written as a subtitle track - dialogue only, no sound cues - then converting it produces a file that passes a format check but fails an FCC hearing-accessibility audit.

For English closed captions going to a US broadcaster or a platform with FCC compliance requirements, I handle the closed-caption workflow end-to-end - from caption creation through SCC export and caption-inspector QC. If the project also needs subtitle translation into another language alongside the English captions, the subtitle translation service covers that path.

FAQ

What is drop-frame timecode, and why does SCC need it?

NTSC video runs at exactly 29.97 fps, not a clean 30 fps. Drop-frame timecode compensates by skipping frame numbers 0 and 1 at the start of each minute (except every 10th minute), keeping the timecode clock aligned with real-world time. In SCC files, drop-frame uses semicolons: 00:00:59;29 is followed by 00:01:00;02 (skipping ;00 and ;01). Non-drop-frame uses colons. For a 30-minute broadcast program, non-drop-frame drifts by roughly 2 seconds - enough to put captions visibly out of sync on a real decoder. Using ScenaristClosedCaptionsDropFrame and --fps:29.97 in SeConv handles this automatically.

What is the difference between SCC and MCC caption files?

SCC (Scenarist Closed Captions) carries only CEA-608 data. MCC (MacCaption) carries both CEA-608 and CEA-708 data in a single file wrapped in a proprietary VANC format. Broadcasters that need 708 (for HD styling or multiple service windows) may ask for MCC. However, open-source MCC export - including Subtitle Edit's MacCaption output - can produce an unreliable CEA-708 service layer. In my workflow, I deliver 708-service content as SMPTE-TT (ST 2052-1) XML rather than as a hand-built MCC, and use SCC for 608-only deliverables. The caption QC page has more detail on format selection.

What happens if my SRT lines are longer than 32 characters?

Behavior varies by encoder. SeConv may silently truncate the line at 32 characters, or try to wrap the overflow onto an additional row. Either way, what a viewer sees will differ from the SRT. The safe workflow: enable the character-count display in Subtitle Edit (View > Show character count per line) and split any line over 32 characters manually before running seconv. For a consistent source, Subtitle Edit's "Split long lines" option in Fix common errors can automate this.

Do I need to run caption-inspector on every SCC file?

For broadcast deliverables going to a US broadcaster or a streaming platform that runs automated QC, yes. A broadcaster's ingestion system will decode the SCC and flag control-code errors - a rejection at that stage costs turnaround time and re-delivery fees. Caption-inspector runs in seconds and catches encoding anomalies I would miss on a visual review. For non-broadcast use (an SCC that gets converted back to SRT for internal review), a quick Subtitle Edit "Info" check is usually enough.

How do I check if a video already has embedded captions before converting a new SRT?

Use ffprobe to inspect the stream list first:

ffprobe -v error -show_entries stream=codec_type,codec_name,tags -of default input.mp4

Look for a stream with codec_name=eia_608 or codec_name=mov_text. If embedded captions exist, extracting them with CCExtractor and comparing against your SRT before writing a new SCC is worth five minutes of work to avoid overwriting existing content.

Official Sources

Written by Dao Huy (Lucas), Vietnamese translator & localization specialist (EN · ZH · FR → Vietnamese). See translation services →

报价WhatsApp