SRT & VTT to JSON — Timestamped Transcript Chunks avatar

SRT & VTT to JSON — Timestamped Transcript Chunks

Pricing

$10.00 / 1,000 parsed subtitle files

Go to Apify Store
SRT & VTT to JSON — Timestamped Transcript Chunks

SRT & VTT to JSON — Timestamped Transcript Chunks

Parse SRT or WebVTT subtitle text into JSON cues and transcript chunks with source timestamps. Preserve raw text and cue references; flag overlaps. $0.01 per file, up to 1 MiB.

Pricing

$10.00 / 1,000 parsed subtitle files

Rating

0.0

(0)

Developer

Stefan Schellen

Stefan Schellen

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 hours ago

Last modified

Categories

Share

Turn an existing subtitle file into structured cues, readable text and chunks that retain references to the source timings. Useful for transcript search, summarization and retrieval workflows where an answer must point back to a moment in a recording. No transcription, video download, translation, LLM call or extra provider key.

Quick start

Paste decoded subtitle text into subtitleText. The prefilled example is synthetic. format defaults to auto; WebVTT must begin with WEBVTT, otherwise SRT is assumed. chunkChars defaults to 1200.

{"subtitleText":"1\n00:00:01,000 --> 00:00:03,000\nWe sold 20 units in 2026.","chunkChars":1200}

The default dataset receives one envelope containing text, cues, chunks, warnings, cueCount, chunkCount, format and schemaVersion.

{"index":0,"startMs":1000,"endMs":3000,"cueIndexes":[0],"text":"We sold 20 units in 2026."}

This is an example chunk. Each cue also preserves its input identifier, rawText, display settings, start/end milliseconds and cleaned text. Recognized formatting tags and WebVTT inline timestamp tags are removed from cleaned text; character entities are decoded. Unknown tags remain. Treat both raw and cleaned text as untrusted input, never executable HTML.

Why use this instead of stripping timestamps?

A simple regex can be enough for plain text. This tool retains time ranges and source cue indexes so downstream answers can cite the original recording. Whole cues are retained, including numeric dialogue and multiline text. An input-order transcript and warnings make overlapping or out-of-order cues visible instead of silently sorting or changing them.

chunkChars is a SOFT character target, not a token limit. Cues are never split or repeated. A single cue larger than the target becomes its own chunk with a warning. Chunk time bounds are the minimum start and maximum end of their cues; they are not word-level alignment or semantic topic detection. Rolling auto-captions are not deduplicated. No arbitrary text is silently discarded to force a size target.

Scope and limits

  • One text file per run: at most 1 MiB UTF-8 and 10,000 cues. Output JSON at most 16 MiB.
  • Strict SRT: numeric cue index, HH:MM:SS,mmm --> HH:MM:SS,mmm, nonempty text, blank lines between cues. Proprietary SRT positioning extensions are rejected.
  • WebVTT: header followed by blank line, optional cue identifiers, millisecond timing lines and preserved display settings. NOTE, STYLE and REGION blocks are counted and skipped; header metadata is not interpreted. No CSS/layout validation or full WebVTT conformance claim.
  • CRLF/CR/LF and leading BOM supported. The caller decodes binary files into Unicode; no automatic legacy-encoding detection.
  • End must be after start. Invalid blocks, ambiguous missing separators and exceeding limits fail the run, rather than returning a partial transcript.
  • No file URLs or network fetching. Input/output are stored by Apify under your retention settings; this is not a zero-retention service.

Price

$0.01 per successfully parsed file within the limits, not per cue or chunk. Rejected files do not trigger our parsing charge. Platform usage is included in this Actor's price; check the live Pricing tab. An Apify account is required.

HTTP / Python example

import os, requests
from pathlib import Path
r = requests.post(
'https://api.apify.com/v2/acts/creatieve_naald~srt-vtt-to-json/run-sync-get-dataset-items',
headers={'Authorization':'Bearer '+os.environ['APIFY_TOKEN']},
params={'maxTotalChargeUsd':'0.01'},
json={'subtitleText':Path('captions.srt').read_text(encoding='utf-8-sig'), 'chunkChars':1200},
timeout=60,
)
r.raise_for_status()
rows = r.json()
if not rows:
raise RuntimeError('No output; inspect the Actor run')
for chunk in rows[0]['chunks']:
print(chunk['startMs'], chunk['endMs'], chunk['text'])

In Make or n8n, download the subtitle in your existing workflow, decode its bytes to text, then send that string as subtitleText through an HTTP node. Iterate chunks for downstream processing and keep cueIndexes, startMs and endMs alongside your text. This does not solve file-access permissions or download failures.

Free alternatives and tested limits

For simple extraction, Make's text tools or a short Code node may be sufficient. Python srt, pysrt and webvtt-py are free local alternatives with different parsing behavior. You are paying for hosted execution, the documented schema and timestamp-preserving chunking, not an exclusive algorithm.

42 local tests cover timestamp parsing, WebVTT blocks, Unicode, numeric dialogue, source mapping, limits, rejected inputs, process timeout and storage/billing behavior. This does not establish compatibility with every subtitle dialect or demonstrate customer demand. Public sample content is synthetic. Share only redacted synthetic examples in support issues.

Troubleshooting: fix the input before retrying

The run's key-value store may contain an ERROR record with an error.code.

  • NON_POSITIVE_DURATION: a cue ends at or before its start. Correct the source timing; the parser does not guess a replacement duration.
  • MISSING_WEBVTT_HEADER or MISSING_HEADER_SEPARATOR: for WebVTT, include the WEBVTT header and its blank-line separator. Setting format to vtt does not convert SRT syntax.
  • MISSING_SRT_INDEX or INVALID_SRT_INDEX: strict SRT requires a numeric identifier before each timing line.
  • AMBIGUOUS_CUE_SEPARATOR: separate cues with a blank line; do not place another timing line inside a cue's dialogue.
  • INVALID_CHUNK_SIZE: use an integer from 100 to 8000. This is a soft character target, not a token budget.

Example of a valid strict SRT cue:

1
00:00:01,000 --> 00:00:03,000
A complete sentence.

If your HTTP request times out, inspect the existing Apify run and its dataset before retrying. A lost response may hide a successful, charged run. Automatic replacement runs can duplicate processing. A rejected file has no successful-parsing event; review its error and fix the input first. Use only synthetic, redacted excerpts when asking for support.