Skip to content

Commit 17ab90b

Browse files
committed
chore: update package description and enhance README for clarity and usability
- Revised package.json description to better reflect functionality for AI summaries and workflows. - Expanded README to provide a clearer overview of features, usage, and benefits, including a focus on timestamped transcripts and video metadata. - Improved formatting and structure for better readability and user engagement.
1 parent d7e5dfd commit 17ab90b

2 files changed

Lines changed: 78 additions & 30 deletions

File tree

README.md

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,43 @@
1-
# youtube-caption-extractor
2-
3-
Extract readable transcripts and basic metadata from public YouTube videos with
4-
one small TypeScript library. It works with manual captions and YouTube's
5-
auto-generated captions, and it can run in Node.js, serverless functions, edge
6-
runtimes, or a containerized API.
7-
8-
- **Simple API**`getSubtitles()` and `getVideoDetails()`
9-
- **Typed output** — ships first-party TypeScript definitions
10-
- **Runtime-friendly** — uses global `fetch`, with an optional custom transport
11-
- **Production-aware** — supports retries, caching, and proxy/custom egress
12-
- **Demo included** — a Next.js sample app plus a Cloudflare Container API
1+
<div align="center">
2+
<h1>youtube-caption-extractor</h1>
3+
<p><strong>Turn public YouTube videos into clean, timestamped transcripts for search, RAG, and slide ready notes.</strong></p>
4+
<p>
5+
Extract YouTube captions, subtitles, auto-generated transcripts, and video metadata
6+
with a tiny TypeScript library: ~10.8 kB packed, ~31.1 kB unpacked.
7+
</p>
8+
<p>
9+
<a href="https://www.npmjs.com/package/youtube-caption-extractor"><img alt="npm version" src="https://img.shields.io/npm/v/youtube-caption-extractor?color=cb3837"></a>
10+
<a href="https://www.npmjs.com/package/youtube-caption-extractor"><img alt="npm downloads" src="https://img.shields.io/npm/dm/youtube-caption-extractor"></a>
11+
<a href="./LICENSE"><img alt="license" src="https://img.shields.io/npm/l/youtube-caption-extractor"></a>
12+
<a href="https://www.typescriptlang.org/"><img alt="TypeScript ready" src="https://img.shields.io/badge/TypeScript-ready-3178c6"></a>
13+
<a href="https://nodejs.org/"><img alt="Node.js 18+" src="https://img.shields.io/badge/Node.js-18%2B-43853d"></a>
14+
</p>
15+
<p>
16+
<a href="#try-it-quickly">Quickstart</a>
17+
· <a href="https://youtube-caption-extractor.vercel.app/">Live demo</a>
18+
· <a href="./sample">Sample app</a>
19+
· <a href="#api">API</a>
20+
· <a href="#deployment-notes">Deployment notes</a>
21+
</p>
22+
</div>
23+
24+
---
25+
26+
## Why use it?
27+
28+
- **One-call transcript extraction**`getSubtitles()` returns timestamped segments ready for search, summarization, indexing, RAG, slide ready research notes, or export.
29+
- **Metadata included**`getVideoDetails()` returns title, description, and captions in one response.
30+
- **Manual + auto captions** — prefers exact language matches, then gracefully falls back to available tracks.
31+
- **Tiny install**~10.8 kB packed on npm, with only two runtime dependencies.
32+
- **Runtime-friendly** — uses global `fetch`, with an optional custom transport for retries, caching, regional routing, or proxies.
33+
- **Production-aware sample** — includes a Next.js demo plus a token-protected Cloudflare Container API.
34+
35+
## Built for
36+
37+
- YouTube caption extraction, subtitle extraction, and timestamped transcript data.
38+
- AI summaries, search indexes, RAG pipelines, and agent workflows that need clean video text.
39+
- Slide ready notes, presentation research, and content workflows built from public YouTube videos.
40+
- Lightweight video metadata enrichment without pulling in a large SDK.
1341

1442
```ts
1543
import { getSubtitles } from 'youtube-caption-extractor';
@@ -71,11 +99,11 @@ The library exports two functions and three types.
7199

72100
Returns the caption track as an array of timed segments.
73101

74-
| Param | Type | Default | Notes |
75-
|---|---|---|---|
76-
| `videoID` | `string` | (required) | The 11-character YouTube video ID, e.g. `7GeFt8suV8E`. Not the full URL. |
77-
| `lang` | `string` | `'en'` | ISO language code (`'en'`, `'es'`, `'fr'`, `'ja'`, …). Manual captions are preferred over auto-generated, and an exact match is preferred over a partial match. |
78-
| `fetch` | `typeof fetch` | global `fetch` | Custom fetch implementation. Useful for adding caching, custom retries, or routing through a proxy. See [Customizing the transport](#customizing-the-transport). |
102+
| Param | Type | Default | Notes |
103+
| --------- | -------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
104+
| `videoID` | `string` | (required) | The 11-character YouTube video ID, e.g. `7GeFt8suV8E`. Not the full URL. |
105+
| `lang` | `string` | `'en'` | ISO language code (`'en'`, `'es'`, `'fr'`, `'ja'`, …). Manual captions are preferred over auto-generated, and an exact match is preferred over a partial match. |
106+
| `fetch` | `typeof fetch` | global `fetch` | Custom fetch implementation. Useful for adding caching, custom retries, or routing through a proxy. See [Customizing the transport](#customizing-the-transport). |
79107

80108
Resolves to `Subtitle[]`. Returns an empty array if the video plays but has no caption track in the requested language. **Throws** if the video is unavailable on any extraction path (see [Error handling](#error-handling)).
81109

@@ -98,9 +126,9 @@ If subtitles fail to extract but the video metadata is available, `subtitles` wi
98126

99127
```ts
100128
interface Subtitle {
101-
start: string; // Segment start time, seconds
102-
dur: string; // Segment duration, seconds
103-
text: string; // Decoded text content
129+
start: string; // Segment start time, seconds
130+
dur: string; // Segment duration, seconds
131+
text: string; // Decoded text content
104132
}
105133

106134
interface VideoDetails {
@@ -119,7 +147,11 @@ interface Options {
119147
All three are exported by name and can be imported directly:
120148

121149
```ts
122-
import type { Subtitle, VideoDetails, Options } from 'youtube-caption-extractor';
150+
import type {
151+
Subtitle,
152+
VideoDetails,
153+
Options,
154+
} from 'youtube-caption-extractor';
123155
```
124156

125157
## Languages
@@ -132,7 +164,7 @@ The `lang` argument is a hint, not a strict filter. Track selection precedence:
132164
4. **Any track whose `vssId` contains the requested code** (partial match)
133165
5. **The first available track** as a final fallback
134166

135-
If you pass `lang: 'en'` and the video only has Spanish manual captions, you'll get those — the library prefers *some* output over none. If you pass a code that doesn't exist on the video, you'll typically get the video's primary language track. To check whether you got what you asked for, inspect the first segment's text or compare against `VideoDetails.title` / `description`.
167+
If you pass `lang: 'en'` and the video only has Spanish manual captions, you'll get those — the library prefers _some_ output over none. If you pass a code that doesn't exist on the video, you'll typically get the video's primary language track. To check whether you got what you asked for, inspect the first segment's text or compare against `VideoDetails.title` / `description`.
136168

137169
## Error handling
138170

@@ -208,7 +240,7 @@ import { getSubtitles, type Subtitle } from 'youtube-caption-extractor';
208240
async function getSubtitlesWithRetry(
209241
videoID: string,
210242
lang = 'en',
211-
maxAttempts = 3
243+
maxAttempts = 3,
212244
): Promise<Subtitle[]> {
213245
let lastError: unknown;
214246
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -331,10 +363,7 @@ export default {
331363
const subtitles = await getSubtitles({ videoID, lang: 'en' });
332364
return Response.json({ subtitles });
333365
} catch (err) {
334-
return Response.json(
335-
{ error: (err as Error).message },
336-
{ status: 500 },
337-
);
366+
return Response.json({ error: (err as Error).message }, { status: 500 });
338367
}
339368
},
340369
};

package.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "youtube-caption-extractor",
33
"version": "1.10.2",
4-
"description": "A simple and efficient package to scrape and parse captions (subtitles) from YouTube videos, supporting both user-submitted and auto-generated captions with language options.",
4+
"description": "Extract clean, timestamped YouTube captions, subtitles, transcripts, and video metadata for AI summaries, RAG, search, and slide-ready workflows.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
77
"files": [
@@ -17,13 +17,32 @@
1717
},
1818
"keywords": [
1919
"youtube",
20+
"youtube-captions",
21+
"youtube-subtitles",
22+
"youtube-transcript",
2023
"captions",
2124
"subtitles",
25+
"transcript",
26+
"transcripts",
27+
"caption-extractor",
28+
"subtitle-extractor",
29+
"transcript-extractor",
30+
"video-transcript",
31+
"timestamped-transcript",
32+
"video-metadata",
33+
"youtube-metadata",
34+
"slide-ready",
35+
"slides",
36+
"presentation-ready",
37+
"research-notes",
38+
"rag",
39+
"llm",
40+
"ai",
41+
"summarization",
2242
"scraper",
2343
"extract",
2444
"parser",
25-
"video",
26-
"transcript"
45+
"video"
2746
],
2847
"author": {
2948
"name": "Himanshu Gupta",

0 commit comments

Comments
 (0)