Caption Checker

io.github.markksantos由 GitHub 帳號 markksantos 發布v1.3.3更新於 Nov 1, 2026

Check, fix, convert and retime SRT and WebVTT captions against Netflix, BBC and DCMP limits.

發布方自己的服務:caption.sh

已驗證STDIO僅桌面開發者工具媒體與設計

概覽

AI 產生的概覽

依 Netflix、BBC 與 DCMP 字幕規範檢查、修正、轉換與重新對時 SRT 及 WebVTT 字幕檔,以本機 stdio 方式執行。

可以做什麼
  • 依 Netflix、BBC 或 DCMP 的限制檢查字幕檔或貼上的 SRT/VTT 文字,可指定影格率與直式影片
  • 在不需要人工判斷的情況下自動修正字幕,回傳修正後的檔案與變更清單
  • 在 SubRip 與 WebVTT 之間互相轉換,保留文字、時間與格式
  • 透過整體位移、指定起點、影格率換算或兩點同步來重新對時
  • 列出各支援規範的具體限制及其出處頁面
適用情境
適合在處理字幕檔時使用:讓助理依廣播或串流規範核對字幕、產出整理後的副本,或在任務進行中轉換格式並重新同步時間軸。
執行需求
以本機程序透過 stdio 執行,可用 npx 從 GitHub 儲存庫啟動,或安裝為 Claude Code 外掛。需要 Node.js 18 以上版本。執行時不需要 API 金鑰、帳號或網路存取。
安裝前請注意
修正模式會寫入你指定路徑的新檔案,並調整出點時間與換行,但不會更動文字或入點時間;發布前請先檢查結果。含格式標籤或雙講者的字幕會留給人工處理。檔案在本機處理,不會上傳。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Caption Checker,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

caption-checker

Check SRT and WebVTT captions against a published caption standard: Netflix English, the BBC subtitle guidelines or the DCMP Captioning Key. It flags captions that read too fast, lines that are too long, too many lines, captions that stay on screen too short or too long, gaps under the minimum, overlaps and broken timestamps. It can also fix those, convert SRT to WebVTT and back, and retime a file that's out of sync.

No dependencies. Node 18+. The same checker runs in the browser, with no install and no upload, at markstudios.com/tools/caption-checker.

[caption-check flagging a travel vlog's SRT file: 2 of 8 captions meet Netflix English limits]

$ caption-check examples/travel-vlog.srttravel-vlog.srt: 2 of 8 captions meet Netflix English, adult programs  #1  0:00.500 -> 0:03.000  Welcome back to the channel.      ✗ Gap to the next caption is 0 frames at 24 fps (minimum 2)  #3  0:06.600 -> 0:07.100  First,      ✗ On screen 0.50 s (minimum 5/6 of a second)  #4  0:07.200 -> 0:09.000  we packed water, snacks, a rain jacket and a spare battery for the cam      ✗ Reading speed 41.1 characters a second (limit 20)      ✗ Line 1 is 74 characters (limit 42)  ...

The limits

Each limit was read on the standard's own page on 2026-10-15.

Netflix (English)BBCDCMP Captioning Key
Reading speedUp to 20 characters a second (adult), 17 (children’s)160–180 words a minuteUp to 130 / 140 / 160 words a minute (lower / middle / upper level)
Characters a line4237 on broadcast (Teletext)No character count
Lines a caption22; 3 for vertical 9:16 videoNo more than 2 preferred
Shortest time on screen5/6 of a secondAbout 0.3 s a word (advice)40 frames (1 second and 10 frames)
Longest time on screen7 secondsNo number6 seconds
Gap between captions2 frames minimum; gaps under 0.5 s closed to 2 framesIf you leave a gap, at least 1 second (advice)No rule

Sources: Netflix English (USA) Timed Text Style Guide · Netflix General Requirements · Netflix Subtitle Timing Guidelines · BBC Subtitle Guidelines · DCMP Captioning Key: Text · DCMP Captioning Key: Presentation Rate

How it counts. Characters include letters, spaces and punctuation, but not line breaks or formatting (<i> tags, {\an8} codes, WebVTT voice spans). Reading speed is characters ÷ (out-time − in-time). Words are runs of characters that hold a letter or a digit, so speaker labels and sound tags count, as DCMP asks. Gaps run from one caption's out-time to the next caption's in-time, in frames at the frame rate you give. Anything a standard words as a recommendation is reported as advice, not as a failure.

CLI

npx github:markksantos/caption-checker#v1.3.3 captions.srt# or: git clone --depth 1 --branch v1.3.3 https://github.com/markksantos/caption-checker && node caption-checker/bin/caption-check.js captions.srt# (#v1.3.3 and --branch v1.3.3 pin a tagged release; without them you get whatever is on main)
caption-check <file.srt|file.vtt> [more files] [options]  -s, --standard <id>   netflix | netflix-kids | bbc | dcmp-upper | dcmp-middle | dcmp-lower  (default: netflix)  -f, --fps <rate>      frame rate for frame-gap checks (default: 24)      --vertical        9:16 video (the BBC allows three lines)      --json            JSON output      --advice          also print advice-only notes      --fix <out>       write a fixed copy to <out> (one input file)      --mcp             run as an MCP server on stdio
caption-check <file> --to vtt|srt [--speakers] [--crlf] [--out <file>]                     convertcaption-check <file> --shift <time> [--from <n>] | --start-at <n=time> | --rate <from:to> | --sync <n=time,n=time>              [--to vtt|srt] [--out <file>]                                                retime

It exits with 1 when any caption breaks a limit, so it works as a CI check before captions ship.

Fix mode

--fix writes a copy with every fix that doesn't need a person: it never changes a word or an in-time.

$ caption-check examples/travel-vlog.srt --fix fixed.srttravel-vlog.srt: 8 changes in 7 captions, written to fixed.srt  #1  Out-time 0:03.000 -> 0:02.916 (to leave 2 frames before the next caption)  #4  Rewrapped to 2 lines (38 + 35 characters)  #5  Out-time 0:17.000 -> 0:16.100 (off an overlap, to the 7 s maximum)  ...  Left for a person (2):  #3  Still on screen only 0.52 s (minimum 5/6 of a second) with no free time after it: merge it with a neighbor or move the next caption  #4  Still reads at 40.2 characters a second (limit 20) with no free time after it: split it, condense it or move the next captionfixed.srt: 6 of 8 captions meet Netflix English, adult programs (before: 2 of 8)
  • Line breaks. A caption with a line over the limit, or too many lines, is rewrapped into the fewest lines that fit, breaking after punctuation where it can and avoiding a break after an article, preposition, conjunction or auxiliary verb ("the", "of", "and", "was"). Captions with formatting tags or two speakers are left for a person.
  • Out-times. An out-time is pulled back off an overlap or a gap under the minimum, cut to the longest time on screen, and pushed into free time when a caption is too short or reads too fast. For Netflix, gaps under 0.5 s are closed to 2 frames, as its timing guide asks.
  • Everything else stays. Captions that needed nothing keep their exact bytes, and so do cue ids, WebVTT headers, NOTE blocks, cue settings, line endings and a byte-order mark. A second run changes nothing.

Run against 300 caption files with all six standards, it never changed a word, an in-time or the number of captions, and never left more captions failing than it started with.

Convert and retime

--to converts SubRip to WebVTT or back; the retiming flags fix captions that are out of sync with the video. Without --out, the file goes to stdout and the summary to stderr.

$ caption-check examples/travel-vlog.srt --to vtt --out travel-vlog.vtttravel-vlog.srt: 8 captions converted from SubRip (.srt) to WebVTT (.vtt).Written to travel-vlog.vtt$ caption-check episode.srt --shift -2.5 --from 120 --out episode.synced.srt     # late by 2.5 s from caption 120 on$ caption-check film.srt --rate 23.976:25 --out film.25fps.srt                     # timed for 23.976 fps, video is 25 fps$ caption-check film.srt --sync 1=0:04.200,640=41:12.5 --out film.synced.srt       # pin two captions, stretch the rest
  • Converting keeps every caption's text and timing. Italic, bold and underline stay; SubRip {\an8}-style position codes become WebVTT line/align settings and back; & and < are escaped for WebVTT and unescaped for SubRip; <v Name> voice tags become "Name: " with --speakers. Whatever the other format can't hold (font colours, NOTE blocks, WebVTT position or size) is listed, not silently dropped.
  • Retiming works on integer milliseconds, so nothing drifts from rounding. A two-point sync says when the stretch matches a common frame-rate pair (23.976/25, 24/25, 29.97/30 ...). Times pushed before 0:00 are clamped and counted.
  • Encodings. Every mode reads UTF-8, UTF-16 (by its byte-order mark) and Windows-1252, the encoding SubRip itself writes by default, and writes UTF-8.

It uses the same reader and writer as the online SRT to VTT converter and subtitle time shifter (subtitles.js is that code, unchanged). Run on 300 caption files (34,836 captions), SRT to WebVTT and back kept every caption's timing, and a shift there and back restored every time.

Library

js
const { parse, check, fix } = require('caption-checker');const result = check(parse(fs.readFileSync('captions.vtt', 'utf8')), 'bbc', { vertical: true });console.log(result.flagged, 'of', result.cues.length, 'captions break a limit');for (const cue of result.cues) for (const issue of cue.issues) console.log(cue.n, issue.severity, issue.message);
const fixed = fix(fs.readFileSync('captions.srt', 'utf8'), 'netflix', { fps: 25 });fs.writeFileSync('captions.fixed.srt', fixed.text);   // also: fixed.changes, fixed.unresolved, fixed.before, fixed.after
const { convert, retime } = require('caption-checker/convert.js');const vtt = convert(srtText, 'vtt');                                   // { text, from, to, captions, notes }const synced = retime(srtText, { rate: { from: 23.976, to: 25 } });    // or { offset: '-2.5', from: 120 }, { startAt: { caption, time } }, { sync: [a, b] }

check() accepts a standard id or your own standard object with the same fields as STANDARDS in index.js.

MCP server and Claude Code plugin

The same checks run as an MCP server, so Claude, Cursor, VS Code and other MCP clients can check a caption file mid-task. Five tools: check_captions (a file path or pasted SRT/VTT text, a standard, fps, vertical), fix_captions (the same arguments; returns the fixed file and what changed), convert_captions (SRT to WebVTT or back), retime_captions (offset, start at, frame-rate change or two-point sync) and list_standards (each limit and the page it comes from). It runs locally: no key, no network.

# Claude Code plugin (MCP server + a caption QA skill)/plugin marketplace add markksantos/caption-checker/plugin install caption-checker@caption-checker
# or the server on its ownclaude mcp add caption-checker -- npx -y github:markksantos/caption-checker#v1.3.3 --mcp

Other clients:

json
{ "mcpServers": { "caption-checker": { "command": "npx", "args": ["-y", "github:markksantos/caption-checker#v1.3.3", "--mcp"] } } }

The skill in skills/caption-checker/SKILL.md tells an agent which standard to pick, how to report results and how to fix a caption without changing its words. skills/caption-fixer/SKILL.md covers fixing a file: what fix_captions changes, and what to do with the captions it leaves for a person. skills/caption-converter/SKILL.md covers converting between SRT and WebVTT and working out which kind of timing fix an out-of-sync file needs.

Study

study/ holds the code and data behind the caption reading speed study: 339,521 captions in 387 NASA videos and MIT OpenCourseWare lectures, measured with this library.

study-auto-captions/ holds the YouTube auto-caption accuracy study: automatic vs human captions on 299 videos, plus caption coverage of the most-subscribed channels.

study-dubbing/ holds the YouTube dubbing study: every audio track on 485 videos from the 97 most-subscribed channels, split into the channels' own dubs and YouTube's automatic ones.

study-video-length/ holds the YouTube video length study: durations of 2,859 latest videos and the Shorts share of 1,484 recent uploads on the most-subscribed channels.

Version history

See CHANGELOG.md and releases.

Tests

npm test

License

MIT © Mark Studios, a video editing and production studio.

來源:README.md,提交 4a504ed

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:該軟體包類型無法在沙箱中執行。

版本歷史

3
  1. v1.3.3最新Nov 1, 2026
  2. v1.3.1Oct 30, 2026
  3. v1.1.0Oct 19, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Caption 整合