youtube-caption-timestamp
v0.1.0
Published
Parse WebVTT/SRT caption files and build deep-linkable YouTube URLs anchored at specific timestamps
Maintainers
Readme
youtube-caption-timestamp
A small, zero-dependency utility for parsing WebVTT and SRT caption files and turning each cue into a deep-linkable YouTube URL anchored at the cue's start time.
Useful for:
- Language learners who want to save interesting sentences with a one-click jump back to the exact moment in the video.
- Note-taking tools that cite video sources precisely.
- Browser extensions that turn subtitles into clickable transcripts.
Install
npm install youtube-caption-timestampNo runtime dependencies.
Usage
const {
parseCaptions,
toDeepLink,
captionsToDeepLinks,
} = require('youtube-caption-timestamp');
// 1. Parse a caption file (WebVTT or SRT — both work)
const vtt = `WEBVTT
00:00:03.200 --> 00:00:05.800
The mitochondria is the powerhouse of the cell
00:00:06.000 --> 00:00:08.500
but it was not always that way
`;
const cues = parseCaptions(vtt);
// [
// { start: 3.2, end: 5.8, text: 'The mitochondria is the powerhouse of the cell' },
// { start: 6.0, end: 8.5, text: 'but it was not always that way' }
// ]
// 2. Build a deep link to any second
toDeepLink('dQw4w9WgXcQ', 3.2);
// → 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=3s'
toDeepLink('dQw4w9WgXcQ', 3605, { short: true });
// → 'https://youtu.be/dQw4w9WgXcQ?t=1h5s'
// 3. Or do both in one step — every cue gets its own URL
captionsToDeepLinks(vtt, 'dQw4w9WgXcQ');
// [
// { start: 3.2, end: 5.8, text: '…', url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=3s' },
// …
// ]API
parseCaptions(input: string): Cue[]
Parses WebVTT or SRT content. Returns an array of cues, each with
{ start, end, text } where start and end are in seconds.
The parser accepts both the 00:00:00.000 (WebVTT) and 00:00:00,000
(SRT comma) timestamp forms, and tolerates files without sequence numbers.
toDeepLink(videoId: string, seconds: number, opts?: { short?: boolean }): string
Returns a YouTube URL of the form
https://www.youtube.com/watch?v=<id>&t=<time>.
Pass { short: true } to get a youtu.be/<id>?t=<time> short link instead.
The t= value uses YouTube's preferred compact format (45s, 2m5s, 1h5s)
and omits zero-valued units.
captionsToDeepLinks(input, videoId, opts?): CueWithUrl[]
Convenience combo of parseCaptions + toDeepLink. Returns the cue array
with an extra url field on each cue.
parseTimestamp(ts: string): number
Low-level helper — converts a single timestamp like "01:23.456" or
"00:01:23,456" to seconds. Exposed so that custom parsers can reuse it.
formatTimeParam(seconds: number): string
The inverse — turns a number of seconds into YouTube's &t= query
format. Exposed for callers that build YouTube URLs their own way.
Background
I started writing this while working on tubevocab.com, an interactive-subtitle reader for English learners that lets you click any word in a YouTube video's captions to see a translation and save the word as a flashcard. One of the things we kept needing was the ability to hand a learner a link back to the exact moment a word appears — not "watch the whole video again," but "jump to 3:42 where the speaker said this."
YouTube's &t= parameter is the standard answer, but the caption formats
(WebVTT, SRT) use a different time representation, and getting the conversion
exactly right across edge cases (hours, decimals, SRT commas, zero-value
units) is annoying to re-derive every time. This library is the piece that
does it once, tested.
The code is framework-agnostic and has no runtime dependencies, so it is happy to run in Node, browser, Deno, or a build pipeline.
License
MIT. See LICENSE.
Contributions and bug reports welcome on GitHub.
