headless-youtube-captions
v3.0.0
Published
Extract YouTube video transcripts, channel videos, comments, search results, and video metadata via yt-dlp
Downloads
316
Maintainers
Readme
Headless YouTube Captions
Extract YouTube transcripts, channel videos, comments, search results, and video metadata using yt-dlp
Features
- Transcripts/captions in multiple languages
- Channel video listings with pagination
- Channel-scoped video search
- Global YouTube search
- Video comments with sort options
- Full video metadata (description, tags, categories, like/view counts)
- Zero npm dependencies — uses yt-dlp CLI
- Modern ES modules with TypeScript definitions
Prerequisites
yt-dlp must be installed and available in your PATH.
# macOS
brew install yt-dlp
# pip
pip install yt-dlp
# Linux
sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
sudo chmod a+rx /usr/local/bin/yt-dlpInstallation
npm install headless-youtube-captionsUsage
Extract Video Transcripts
import { getSubtitles } from 'headless-youtube-captions';
const captions = await getSubtitles({
videoID: 'dQw4w9WgXcQ',
lang: 'en' // Optional, default: 'en'
});
// => [{ start: "0.0", dur: "3.0", text: "We're no strangers to love" }, ...]Get Channel Videos
import { getChannelVideos } from 'headless-youtube-captions';
const result = await getChannelVideos({
channelURL: '@mkbhd', // or full URL, or channel ID
page: 1, // Optional, default: 1
pageSize: 20 // Optional, default: 20
});
console.log(result.videos);
// => [{ id, title, views, uploadTime, duration, thumbnail, url }, ...]
console.log(result.hasMore); // true if more pages availableSearch Channel Videos
import { searchChannelVideos } from 'headless-youtube-captions';
const result = await searchChannelVideos({
channelURL: '@mkbhd',
query: 'iphone review',
page: 1, // Optional
pageSize: 20 // Optional
});
console.log(result.results);Search YouTube Globally
import { searchYouTubeGlobal } from 'headless-youtube-captions';
const result = await searchYouTubeGlobal({
query: 'javascript tutorial',
page: 1, // Optional, default: 1
pageSize: 10 // Optional, default: 10
});
console.log(result.results);
// => [{ id, type: 'video', title, url, channel, views, duration, uploadTime, thumbnail }, ...]Get Video Comments
import { getVideoComments } from 'headless-youtube-captions';
const result = await getVideoComments({
videoID: 'dQw4w9WgXcQ',
sortBy: 'top', // Optional, 'top' or 'newest', default: 'top'
page: 1, // Optional
pageSize: 20 // Optional
});
console.log(result.comments);
// => [{ author, authorUrl, text, time, likes, isReply }, ...]Get Video Metadata
import { getVideoMetadata } from 'headless-youtube-captions';
const result = await getVideoMetadata({
videoID: 'dQw4w9WgXcQ'
});
console.log(result.video);
// => { id, title, description, uploadDate, viewCount, likeCount, duration, tags, categories }
console.log(result.channel);
// => { name, url, subscriberCount }Pagination
All list-returning functions use page and pageSize parameters:
| Function | Default pageSize | Pagination type |
|----------|-----------------|-----------------|
| getChannelVideos | 20 | Server-side (only fetches requested page) |
| searchChannelVideos | 20 | Server-side |
| getVideoComments | 20 | Fetch up to pagepageSize, return slice |
| searchYouTubeGlobal | 10 | Fetch up to pagepageSize, return slice |
All results include a hasMore boolean to indicate if more pages are available.
API Reference
getSubtitles({ videoID, lang? })
Returns Promise<{ start: string, dur: string, text: string }[]>
getChannelVideos({ channelURL, page?, pageSize? })
Returns Promise<{ channel, videos, page, pageSize, hasMore }>
searchChannelVideos({ channelURL, query, page?, pageSize? })
Returns Promise<{ query, results, page, pageSize, totalFound, hasMore }>
getVideoComments({ videoID, sortBy?, page?, pageSize? })
Returns Promise<{ comments, page, pageSize, totalFetched, hasMore, sortBy }>
searchYouTubeGlobal({ query, page?, pageSize? })
Returns Promise<{ query, results, page, pageSize, hasMore }>
getVideoMetadata({ videoID })
Returns Promise<{ video, channel }> — no pagination needed.
Requirements
- Node.js 18+
- yt-dlp installed and in PATH
License
MIT
