How to generate an SRT file from a video

To generate an SRT file from a video, transcribe it with timestamps and write each timed sentence as a numbered block. Sume's STT returns timed JSON.

5 min readSume
All posts

To generate an SRT file from a video, transcribe its speech with timestamps and write each line as a numbered block: the number, a start --> end timing line, and the text. Sume's speech-to-text returns JSON rather than an .srt file, but it holds what an SRT needs: ask for sentence segmentation and you get segments[], each with text, start, and end in seconds, one block per segment.

Sume facts come from the Video inspect docs and the STT 1.0 schema in the Sume API reference, read on 2026-09-27. The SRT layout itself is the plain-text subtitle format, not a Sume feature. For the raw transcript fields, see speech-to-text with word timestamps.

How do I get timed sentences from the video?

Two Sume calls return timed sentences, and both take segmentation: { "mode": "sentence" } plus an optional language_code hint (omit it for auto-detect):

From Video inspect and the Sume API reference, read 2026-09-27.
Video inspectSTT 1.0
RoutePOST /v1/video-inspect with transcribe: truePOST /v1/stt-1.0/transcribe
Inputvideo_url: a media.sume.com clip in your workspace, such as an earlier Sume job's outputaudio_url: a public HTTPS audio file, such as the video's soundtrack
Word timesSeconds from the start of the videoSeconds from the start of the audio
Where segments landThe inspect's transcript.segments[]segments[] on the job result
BillingProbe and stills unbilled; the transcript bills at the STT 1.0 rateThe STT 1.0 rate
curl -X POST https://api.sume.com/v1/video-inspect \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: srt-transcript-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
    "frames": false,
    "transcribe": true,
    "segmentation": { "mode": "sentence" }
  }'

How do I write the SRT file from the segments?

Inspect waits up to 30 seconds by default and answers 200 with the finished inspect, or 202 with a job to poll; read it later with GET /v1/video-inspect/:id. Then write one block per segment:

  • Number the blocks 1, 2, 3 in order. STT 1.0 numbers its segments from zero.
  • Write each time as HH:MM:SS,mmm, with a comma before the milliseconds.
  • Put the timing line under the number, the text under it, and a blank line after each block.
  • Segments are gapless: each one ends where the next begins, so a line stays up through a pause. To end a block at the last spoken word instead, take that word's end from words[].
def timecode(t):
    ms = round(t * 1000)
    h, ms = divmod(ms, 3_600_000)
    m, ms = divmod(ms, 60_000)
    s, ms = divmod(ms, 1000)
    return f"{h:02}:{m:02}:{s:02},{ms:03}"

def segments_to_srt(segments):
    blocks = []
    for n, seg in enumerate(segments, start=1):
        times = f"{timecode(seg['start'])} --> {timecode(seg['end'])}"
        blocks.append(f"{n}\n{times}\n{seg['text'].strip()}\n")
    return "\n".join(blocks)

Can I make a WebVTT file instead?

Yes, from the same segments. A WebVTT file starts with a WEBVTT line and a blank line, writes the milliseconds after a period instead of a comma, and does not need the block numbers. Everything else in the loop stays the same.

To burn the lines into the picture instead of shipping a separate file, send them as cues, as in burn an SRT file into a video.

What does it cost, and what are the limits?

  • The transcript bills at the STT 1.0 rate, $0.01 per audio minute on API pricing, plus a 5.5% agent fee by default. An inspect's probe and stills are unbilled.
  • Without duration_seconds, a transcript reserves 1 minute; the hint tops out at 600 seconds. Inspect reads sources up to 1,800 seconds.
  • A clip with no audio track fails inspect with inspect_source_has_no_audio. Check probe.has_audio first with a frames: false inspect.
  • The transcript comes back as JSON fields, not as a subtitle file. A caption job does not hand back its transcript either: raw transcripts are not part of that resource's public contract.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume