← Back to Blog
Tutorials & How-Tos

Remotion Captions: SRT, Word Timing, and Subtitle Export

Imported SRT cues and genuinely word-timed captions solve different editing problems. This documentation-based guide explains how to preserve whitespace, keep caption clocks consistent, control visibility through pauses and cuts, and choose burned-in subtitles or a separate SRT export.

Written by Hamza Diaz
October 12, 202610 min read23 views

Picture a hypothetical product demo. The transcript is correct, but the highlight follows a whole sentence and the caption hangs around through a pause. More animation will not fix either problem. One needs word timings; the other needs a decision about when text disappears.

Choose the caption behavior before the style. This documentation-based guide covers supplied Remotion captions and subtitle outputs. Its fixture and inspection plan are illustrative and unexecuted, not a tested application or evidence from an Optijara deployment.

Choose cue-level subtitles or genuinely word-timed captions

Use SRT when whole-cue display matches the video

Word highlighting should earn its place. In a narrated screen recording, a complete phrase can give viewers time to read while they watch a command execute.

Remotion's parseSrt reference converts supplied SRT cues into Caption items returned in an object's captions array. Each sentence in its example keeps its cue interval. The parser does not discover when each word was spoken.

Supplied timing granularityDesired displayAdditional workLimitation
Whole-cue SRTPhrase or sentence subtitlesImport, review, and style cuesNo individual-word alignment
Genuine word-timed Caption dataHighlight the spoken wordPreserve tokens, group pages, map the clockSupplied alignment still needs audio review
Sentence-only intervalsIndividual-word highlightingObtain and review word-aligned data firstEqual-duration splitting is not speech alignment

Use word timings when individual words need highlighting

Use word data when highlighting helps someone follow the explanation, perhaps as the narrator says a technical term. Dividing a sentence into equally timed words produces an animation schedule, not evidence about the speech.

The Caption structure accepts either granularity, so the type cannot settle that question. Ask the supplier whether each interval belongs to a cue or a word.

For context on using React for video, Mux's historical programmatic-video example shows a developer-oriented visualization workflow. It is not a reference for current caption APIs or caption accuracy.

Import captions without losing text or timing information

Check the Caption fields and whitespace convention

Read the documented fields literally. text holds the caption, while startMs and endMs bound its interval. timestampMs holds a singular timestamp or null; confidence holds a number from 0 to 1 or null. A representative timestamp cannot replace an interval boundary.

Keep the spaces in word data, preferably before subsequent words. The utilities are whitespace-sensitive: trimming every token can remove the separators needed for readable text. Carry that convention through any adapter rather than expecting the utility to insert spaces.

The Caption reference recommends white-space: pre to preserve them during rendering. Long technical phrases still need a layout check at the intended video dimensions. Preserved whitespace does not mean the text fits.

Handle loading failures and version-dependent validation

The importing guide uses staticFile() to reference an SRT in public, fetches its text, and passes it to parseSrt. Its asynchronous pattern holds rendering with useDelayRender(), calls continueRender(handle) after loading succeeds, and calls cancelRender(error) on failure.

Check response.ok before reading the response, then validate that the expected captions arrived. MDN explains that fetch does not reject on HTTP error status alone. A resolved request can still be an unusable subtitle response. Route parsing and validation failures to cancellation too, rather than releasing a render with accidentally empty captions.

The parser reference documents strict: true from version 4.0.530. The default is false, for tolerant parsing. Strict mode rejects malformed or empty files with cue and line context. Check your installed version before adding it.

The example's confidence: 1 comes from the parser. It is not a measured speech-recognition accuracy score. Wording still needs audio review. Similarly, pageBreakAfter, available from 4.0.517, forces a break without changing timing, as the Caption reference explains.

The Cue, Clock, Cut playbook for caption visibility

Cue, Clock, Cut is this article's original editorial playbook. It separates grouping from timeline mapping and visibility. It is neither a Remotion feature nor a validated performance framework.

flowchart TD A[Inspect supplied caption intervals] --> B{Individual word timings available?} B -->|No| C[Choose whole cue display or obtain alignment] B -->|Yes| D[Preserve spaces and group words] C --> E[Map captions and frames to one clock] D --> E E --> F[Bound visibility around pauses and cuts] F --> G[Choose video captions or separate SRT] G --> H[Review against audio and destination playback]

Cue: group text without inventing alignment

createTikTokStyleCaptions turns correctly spaced data into pages. combineTokensWithinMilliseconds controls grouping duration. Once a page exceeds that duration, the next caption starting with a space begins a new page. The setting cannot supply missing word timings or detect silence in audio; it is not an exact word-count control either.

This typed fixture shows the spacing convention. Its lowercase tokens name the playbook stages, and its intervals are invented for instruction. The fragment was not executed and is not a complete application or an actual transcript.

import type {Caption} from '@remotion/captions';

const illustrativeCaptions: Caption[] = [
  {text: 'cue', startMs: 1000, endMs: 1300, timestampMs: null, confidence: null},
  {text: ' clock', startMs: 1300, endMs: 1500, timestampMs: null, confidence: null},
  {text: ' cut', startMs: 1500, endMs: 1900, timestampMs: null, confidence: null},
];

The leading spaces matter. So do the separate intervals. Formatting preserves the supplied information; it does not establish that the timings are correct.

Clock: compare timestamps in the same coordinate system

Page tokens carry absolute fromMs and toMs values in the supplied caption timeline. The displaying guide compares them with frame-derived time. Before copying that example, define where your caption timeline begins.

For a simple offset-only Sequence, useCurrentFrame() shifts by from, and nested sequences cascade, according to the Sequence reference. Trimming, playback-rate changes, loops, or freezes require their own mapping. Map the resulting local frame to caption time once. Applying the offset twice creates a fresh timing error.

Take an illustrative calculation at 30 fps. Assume the sequence starts at composition frame 30, captions use composition time, playback speed is unchanged, and there is no nesting, trim, loop, or freeze. Local frame 0 maps to 1000 ms. Local frame 8 maps to about 1266.67 ms, and local frame 9 to 1300 ms. With a start-inclusive, end-exclusive comparison, the fixture's first word is inactive at the last position. These are arithmetic results, not observed Remotion output.

For boundaries between frames, the proposed inspection convention takes the ceiling of milliseconds multiplied by fps and divided by 1000. Record the convention. Recalculate the mapping whenever an edit changes the source timeline.

The displaying guide uses Sequence, although the current reference no longer recommends direct use for new code. Newer components can expose timing props directly or use Interactive.withSchema(). Check version support before choosing either pattern.

Cut: decide what stays visible through edits and pauses

A page break does not mean the text disappears. The grouping reference documents breakOnSilenceAfterMilliseconds from 4.0.514. It compares caption timestamp gaps, not audio. The previous page lasts until the next page starts, including the pause.

Choose whether that page should persist after its last spoken token. Set rendering bounds for the chosen behavior, including scene cuts and the composition end. The displaying guide applies its own duration cap; grouping alone does not make this decision.

In the hypothetical demo, mark the spoken phrase and its screen action. If the narrator names a button while the cursor points elsewhere, review picture and audio together. Correct the cut or timings, or keep the whole phrase visible. Do not change spoken instructions to match a later interface revision.

Keep the supplied captions intact and edit a separate copy. Record whether timings refer to the recording or the final composition. Document the mapping after removing speech or inserting a screen capture. Note why each disputed phrase was corrected; a correction note does not prove playback was inspected.

Before adding more animation, work through this checklist:

  • Record the caption timeline origin and any edit mapping.
  • Check whether the input has cue or word timings; keep its spaces.
  • Choose grouping duration independently of highlighting.
  • Translate frame time into caption time exactly once.
  • Decide when captions disappear during pauses and at cuts, including the final cue.
  • Choose the destination output and plan boundary inspections.
{"playbook":"cue-clock-cut","cue":"preserve-granularity-and-spaces","clock":"map-caption-time-once","cut":"bound-visibility","inspectionStatus":"proposed-unexecuted"}

What teams get wrong: caption defects and targeted fixes

Separate input problems from grouping and clock problems

Fix the stage that owns the symptom. Changing a font cannot create word alignment. Adjusting grouping will not undo a doubled offset.

Visible symptomLikely causeTargeted correctionProposed check
Words mergeToken spaces were removedRestore the input whitespace conventionCompare assembled text with approved wording
Entire sentence highlightsOnly cue-level SRT timing existsKeep cue display or obtain word alignmentInspect granularity before styling
Highlights lead or lagLocal and caption clocks differMap the offset exactly onceInspect interval boundaries
Text persists through a pauseGrouping was treated as hidingSet deliberate visibility boundsInspect the silent gap
Final cue vanishes or lingersEnd visibility is unbounded or clippedReconcile token end and composition endInspect the last spoken interval
SRT words concatenateExport input lacks spacesPreserve delimiters before serializationRead emitted cue text

GitHub issue 10476 illustrates the confusion historically. The reporter used @remotion/captions@4.0.441. The maintainer confirmed whitespace sensitivity as established behavior, acknowledged separate bugs, and closed the issue as completed. Its proposed option names are not current API instructions, and its closed defects should not be presented as unresolved.

Use a proposed boundary-check plan instead of trusting the preview

Inspect neighboring positions around representative boundaries. For the arithmetic example, proposed composition-frame checks are 29, 30, 38, and 39. They cover the first word's entry and exit under those assumptions. No render test was performed.

Proposed measurementInspection methodEvidence to retain
Cue entry and exitReview neighboring frames and audioFrame positions and correction notes
Page transitionCompare visible text on both sidesIntended grouping and observed screenshots
Pause visibilityInspect after the last word and before the nextChosen hide or persist policy
Cut and final cueReview edited audio and composition boundsEdit mapping and end-state notes
Export consistencyCompare SRT wording and intervals with videoReviewed file and destination playback notes

This plan contains no measured results. Repeat the checks after edits, even if an earlier preview looked right. Speaker information cannot stand in for word timings either. The speaker-to-transcript handoff guide explains the distinction for diarization and ASR. An activity track is not aligned words.

Choose burned-in captions, a separate SRT, or both

Render visible captions into the video

The exporting guide describes burned-in subtitles as caption components rendered into the video. Their appearance becomes part of the pixels. Check whether that suits the destination and leaves important screen content visible.

A selectable caption track is a separate deliverable. If you need a styled video and separately managed subtitles, plan both outputs.

Serialize cues and emit a separate subtitle artifact

The same guide documents serializeSrt() with Artifact to emit a subtitle file during rendering. This article did not generate one.

The serialization reference defines lines as a two-dimensional array: outer items are cues, and inner items concatenate without inserted spaces. Each cue starts at its first item's startMs and ends at its last item's endMs. Keep the order and delimiters intact.

A newline in text makes visual lines within one cue. On supported versions, pageBreakAfter starts another cue. Neither creates speech alignment. When converting grouped page tokens back to captions, keep their original intervals; a page's display duration should not replace the last word's end.

Review the emitted SRT alongside the video in the intended destination. Serialization alone says nothing about upload success or subtitle playback support.

Limitations: readable captions still need audio and output review

Timing quality depends on supplied data and edits

No Remotion installation, transcription, fixture execution, or render was performed for this guide. There were no paid API calls or private-media reads. The numerical examples are arithmetic only.

Compare the transcript with the actual audio, paying attention to technical names and edited passages. The multilingual speech AI test bench offers a related, language-specific example of checking names and workflow usefulness. It is not a provider recommendation here.

Privacy, layout, and accessibility need separate decisions

Before sharing audio with an external service, check permission and its documented data handling. Budget for adaptation and review without assuming savings. Check long phrases at the intended dimensions, especially where subtitles could obscure the interface being demonstrated.

Attractive captions do not establish accessibility conformance. Review wording and timing, include relevant non-speech information, and assess readability and delivery format. For AI-assisted video, visual-content provenance answers a different evidence question. Keep source and edit records separate from audio review, with each supporting only what it actually establishes.

Key Takeaways

  • 1Whole-cue SRT remains cue-level timing after import; individual-word highlighting needs genuinely word-aligned data.
  • 2Preserve whitespace in Caption text because grouping and SRT serialization do not invent missing separators.
  • 3Compare frame-derived time and token intervals in one defined coordinate system, applying offsets only once.
  • 4Page breaks from timestamp gaps do not automatically hide captions during pauses.
  • 5Choose burned-in subtitles, a separate SRT, or both for the actual destination and review playback there.
  • 6The fixture and boundary-check plan are illustrative and unexecuted; supplied wording, timing, and layout still require actual-media review.

Conclusion

Start with the timing you have. Whole-cue SRT can suit a screen recording; individual-word highlights need genuine word timings. Use Cue, Clock, Cut to keep grouping and timeline mapping separate from visibility decisions. Preserve spaces and account for edits, then review the chosen output against audio and destination playback. If your team needs help designing an AI-assisted caption workflow, Optijara offers AI consulting.

Frequently Asked Questions

Can Remotion import an existing SRT subtitle file?

Yes. Fetch the text and call `parseSrt({input: text})` from `@remotion/captions`, then read the returned object's `captions` array. Each supplied cue becomes a Caption item. Handle loading and parsing failures. Optional strict parsing requires version `4.0.530` or later. See the [parser reference](https://www.remotion.dev/docs/captions/parse-srt).

Does importing SRT create word-level timing?

No. A sentence cue supplies one cue interval, not individual spoken-word intervals. Word highlighting needs genuine word timings reviewed against audio. Equal-duration splitting creates an animation schedule, not speech alignment. See the [SRT parsing example](https://www.remotion.dev/docs/captions/parse-srt).

Does breakOnSilenceAfterMilliseconds hide captions during silence?

No. From version `4.0.514`, it creates page breaks using timestamp gaps, without analyzing audio. The previous page lasts until the next starts. Set rendering bounds to hide text during a pause. See the [grouping reference](https://www.remotion.dev/docs/captions/create-tiktok-style-captions).

Why is word highlighting offset inside a Sequence?

`useCurrentFrame()` inside a simple offset-only Sequence is shifted by `from`. Compare it with caption time only after mapping both to one timeline. Nesting, trimming, playback-rate changes, loops, and freezes require their own mapping. See the [Sequence reference](https://www.remotion.dev/docs/sequence).

Can Remotion export captions as a separate SRT file?

Yes. `serializeSrt()` converts Caption groups to SRT text; `Artifact` can emit a separate file during rendering. Preserve spaces and cue boundaries, then review destination playback. See the [subtitle export guide](https://www.remotion.dev/docs/captions/exporting).

Sources

Share this article

Hamza Diaz

Written by

Hamza Diaz

Hamza Diaz is the founder of Optijara, where he builds practical AI agents, automation systems, and Copilot workflows for service businesses. He writes about AI operations, agent strategy, and real-world implementation for teams that want usable systems instead of hype.