← Dev notes

Wrong-time captions are worse than no captions

August 2026 · DeepSRT development notes

Caption engineering that trusts the model's anchors, and never its spans.

The night 1.3.0 went live, we fed it real-world videos — a finance channel's weekend recap, a multi-speaker paranormal podcast, a ghost-hunting field shoot from Malaysia. AI transcription is 1.3.0's headline feature: when a video has no caption track, DeepSRT asks Gemini to “watch” the video itself, and live captions, the transcript pane, and summaries all keep working.

The words were right almost every time. The timing had ideas of its own.

The model can hear, but it can't keep time

The first video came back as 16 cues of exactly 60 seconds each — a full minute of script stacked into a wall on screen. We asked for finer cues; it obliged with 181 beautiful small ones whose timeline drifted steadily: tens of seconds late mid-video, the last cue landing at 4,181 seconds. The video is 858 seconds long.

This is not a prompt bug on our side. It is a Gemini limitation the whole community has documented: it cannot produce SRT-grade timestamps, and granularity trades off against accuracy — demand fine cues and it drifts to pay for them.

To be fair, Google's official documentation never promised caption-grade timing. The capability list says describe, segment, extract, and refer to specific timestamps — and referring to timestamps is not the same job as producing millisecond SRT. YouTube URL input itself is still in preview (free, capped at 8 hours of video a day, rules subject to change). We are building a feature that needs timing precision on a foundation officially labeled preview — which is why every project in the table below turned away at the same wall.

What the docs sayWhat it means for DeepSRT
Preview“The YouTube URL feature is in preview and is available at no charge. Pricing and rate limits are likely to change.”Our preview label isn't caution — the upstream itself isn't settled
QuotaFree tier: at most 8 hours of YouTube video per day, public videos onlyYour daily allowance, straight from the source
CostVideo sampled at 1 FPS; ~100 tokens per second at low media resolution (300 default)We measured ~91 tokens/second — matching the official math, and the reason every request re-ingests the whole video
CapabilityThe list reads: describe, segment, extract information, refer to specific timestampsCaption-grade timing was never promised — referring to timestamps and producing millisecond SRT are different jobs

What everyone else did

Before writing a fix we surveyed the community. We are not the first to hit this wall — and every project ended up choosing some form of surrender:

ProjectThe wall they hitWhat they decided
pyVideoTransGemini cannot produce SRT-grade timestamps; batch jobs also forget formats and re-segment at willStop asking Gemini for time. Download the audio, segment with VAD at millisecond precision, let Gemini do text only
yt-whisper familyNeeds an accurate timelineSkip multimodal models entirely. Download the audio and hand it to Whisper
video-intelChunked transcription misplaces content across chunk timelines, drops hour digits, silently omits passages; a stronger model made it worseGive up on live-grade precision. Offline transcripts for translation and search, defended by chunking, normalization, and coverage checks
gemini-transcribeFine-grained timestamps are unreliableGive up on granularity. Advertises “logically grouped timestamps” — for reading, not for syncing a player

See the pattern? Whoever can get the audio escapes to VAD and Whisper; whoever can't gives up on precise time. Neither road is open to us — DeepSRT does not download videos, which is both a product promise and the reason this feature exists; yet live captions must keep time. We are attempting something with no public precedent of success.

Our call: trust the anchors, never the spans

After enough measurement a pattern emerged: when the model says a sentence starts at a given second, that is roughly trustworthy. When it says how long the sentence ran, it is frequently making that up.

How badly? On a 33-minute video the model claimed one 22-character cue spanned 2,723 seconds. Another run claimed wall-to-wall coverage — but divide characters by claimed time and the speaking rate is 0.3 characters per second. Spoken Chinese runs three to six. Nobody talks slower than incense burns.

So the 1.4.0 caption engine draws its trust boundary there:

A hole beats a guess

The hardest lesson came from the ghost-hunting video. Long B-roll, ambient noise, intermittent dialogue — the model packed scattered phrases from several minutes into one cue. Compressing that text back to its anchor is wrong (words appear on screen six minutes early); spreading it across the span is wrong too (every line smeared for twenty seconds). Both are guesses.

The ghost-hunting video playing in DeepSRT with AI live captions and the transcript pane
The hardest-lesson video itself: a ghost-hunting field shoot — long B-roll, intermittent dialogue — with AI captions and the transcript pane working off a video that has no caption track.

So we don't guess: a packed cue is dropped, and its span becomes a hole. The engine audits coverage segment by segment, and re-transcribes exactly the ranges that are missing — a ranged question usually gets a properly timed ranged answer. Whatever still can't be filled is honestly labeled on screen: these minutes could not be transcribed.

Screams, crowds, and music have no transcribable speech in the first place. A blank is not a failure — pretending is.

Honestly: this is not perfect yet

That table deserves a second look — project after project turned away from precise timing, not for lack of effort, but because under a URL-only constraint there is no perfect solution yet. Our approach moves live captions from “unusable” to “keeps up”, but alignment is paragraph-grade, and there will still be moments half a beat behind.

So here is our honest recommendation: treat AI summaries and the transcript as the main feature — those are solid; treat live captions as a reference. This part needs more polish and will keep getting it — which is exactly why the feature is labeled preview, ships off by default, uses your own key, and why Settings reminds you to set a monthly spending cap first.

Videos with captions are untouched — native caption tracks always win, and AI transcription only steps in when a video truly has none.

1.4.0 release notes

A fancam playing full-window in DeepSRT with AI live captions
The hidden-panes layout: the whole window belongs to the video. This fancam has no caption track — the lyrics are AI-transcribed live.
LISA's lie detector interview full-window with translated live captions
Native English captions translated to Chinese on the fly, in the maximized layout.
Tip: resize live captions with the + / − keys, and move them by click-dragging — ridiculously simple, try it.

DeepSRT is a one-time purchase on the Mac App Store. AI transcription needs your own Gemini API key. 1.4.0 is in review now.