youtube-knowledge-mcp 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +166 -33
- package/dist/brain-schemas.d.ts +502 -0
- package/dist/brain-schemas.d.ts.map +1 -0
- package/dist/brain-schemas.js +109 -0
- package/dist/brain-schemas.js.map +1 -0
- package/dist/http/app.d.ts +16 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +176 -0
- package/dist/http/app.js.map +1 -0
- package/dist/http/auth.d.ts +38 -0
- package/dist/http/auth.d.ts.map +1 -0
- package/dist/http/auth.js +79 -0
- package/dist/http/auth.js.map +1 -0
- package/dist/http/config.d.ts +41 -0
- package/dist/http/config.d.ts.map +1 -0
- package/dist/http/config.js +65 -0
- package/dist/http/config.js.map +1 -0
- package/dist/http/rate-limiter.d.ts +24 -0
- package/dist/http/rate-limiter.d.ts.map +1 -0
- package/dist/http/rate-limiter.js +55 -0
- package/dist/http/rate-limiter.js.map +1 -0
- package/dist/http/sessions.d.ts +34 -0
- package/dist/http/sessions.d.ts.map +1 -0
- package/dist/http/sessions.js +62 -0
- package/dist/http/sessions.js.map +1 -0
- package/dist/http.d.ts +6 -48
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +35 -252
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -431
- package/dist/index.js.map +1 -1
- package/dist/prompts-brain.d.ts +4 -0
- package/dist/prompts-brain.d.ts.map +1 -0
- package/dist/prompts-brain.js +48 -0
- package/dist/prompts-brain.js.map +1 -0
- package/dist/prompts-research.d.ts +4 -0
- package/dist/prompts-research.d.ts.map +1 -0
- package/dist/prompts-research.js +74 -0
- package/dist/prompts-research.js.map +1 -0
- package/dist/prompts-shared.d.ts +13 -0
- package/dist/prompts-shared.d.ts.map +1 -0
- package/dist/prompts-shared.js +7 -0
- package/dist/prompts-shared.js.map +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +5 -58
- package/dist/prompts.js.map +1 -1
- package/dist/registry/brain-tools.d.ts +4 -0
- package/dist/registry/brain-tools.d.ts.map +1 -0
- package/dist/registry/brain-tools.js +104 -0
- package/dist/registry/brain-tools.js.map +1 -0
- package/dist/registry/channel-tools.d.ts +4 -0
- package/dist/registry/channel-tools.d.ts.map +1 -0
- package/dist/registry/channel-tools.js +53 -0
- package/dist/registry/channel-tools.js.map +1 -0
- package/dist/registry/health-tools.d.ts +4 -0
- package/dist/registry/health-tools.d.ts.map +1 -0
- package/dist/registry/health-tools.js +21 -0
- package/dist/registry/health-tools.js.map +1 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +27 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/library-tools.d.ts +4 -0
- package/dist/registry/library-tools.d.ts.map +1 -0
- package/dist/registry/library-tools.js +116 -0
- package/dist/registry/library-tools.js.map +1 -0
- package/dist/registry/media-tools.d.ts +4 -0
- package/dist/registry/media-tools.d.ts.map +1 -0
- package/dist/registry/media-tools.js +100 -0
- package/dist/registry/media-tools.js.map +1 -0
- package/dist/registry/thumbnail-tools.d.ts +7 -0
- package/dist/registry/thumbnail-tools.d.ts.map +1 -0
- package/dist/registry/thumbnail-tools.js +72 -0
- package/dist/registry/thumbnail-tools.js.map +1 -0
- package/dist/registry/transcript-tools.d.ts +4 -0
- package/dist/registry/transcript-tools.d.ts.map +1 -0
- package/dist/registry/transcript-tools.js +68 -0
- package/dist/registry/transcript-tools.js.map +1 -0
- package/dist/registry/types.d.ts +41 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +17 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/registry/video-tools.d.ts +4 -0
- package/dist/registry/video-tools.d.ts.map +1 -0
- package/dist/registry/video-tools.js +101 -0
- package/dist/registry/video-tools.js.map +1 -0
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +75 -6
- package/dist/resources.js.map +1 -1
- package/dist/schemas.d.ts +74 -54
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +30 -4
- package/dist/schemas.js.map +1 -1
- package/dist/thumbnail-resource.d.ts +8 -0
- package/dist/thumbnail-resource.d.ts.map +1 -0
- package/dist/thumbnail-resource.js +38 -0
- package/dist/thumbnail-resource.js.map +1 -0
- package/dist/thumbnail-schemas.d.ts +512 -0
- package/dist/thumbnail-schemas.d.ts.map +1 -0
- package/dist/thumbnail-schemas.js +95 -0
- package/dist/thumbnail-schemas.js.map +1 -0
- package/dist/tools/ask-brain.d.ts +62 -0
- package/dist/tools/ask-brain.d.ts.map +1 -0
- package/dist/tools/ask-brain.js +70 -0
- package/dist/tools/ask-brain.js.map +1 -0
- package/dist/tools/batch.d.ts +10 -10
- package/dist/tools/batch.js +3 -3
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/brain-info.d.ts +180 -0
- package/dist/tools/brain-info.d.ts.map +1 -0
- package/dist/tools/brain-info.js +108 -0
- package/dist/tools/brain-info.js.map +1 -0
- package/dist/tools/build-brain.d.ts +120 -0
- package/dist/tools/build-brain.d.ts.map +1 -0
- package/dist/tools/build-brain.js +123 -0
- package/dist/tools/build-brain.js.map +1 -0
- package/dist/tools/check-health.d.ts +2 -0
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +9 -0
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/clips.d.ts +13 -45
- package/dist/tools/clips.d.ts.map +1 -1
- package/dist/tools/clips.js +52 -128
- package/dist/tools/clips.js.map +1 -1
- package/dist/tools/fetch-channel-thumbnails.d.ts +179 -0
- package/dist/tools/fetch-channel-thumbnails.d.ts.map +1 -0
- package/dist/tools/fetch-channel-thumbnails.js +123 -0
- package/dist/tools/fetch-channel-thumbnails.js.map +1 -0
- package/dist/tools/fetch-videos.d.ts +11 -8
- package/dist/tools/fetch-videos.d.ts.map +1 -1
- package/dist/tools/fetch-videos.js +3 -0
- package/dist/tools/fetch-videos.js.map +1 -1
- package/dist/tools/frames-subtitles.d.ts +44 -0
- package/dist/tools/frames-subtitles.d.ts.map +1 -0
- package/dist/tools/frames-subtitles.js +104 -0
- package/dist/tools/frames-subtitles.js.map +1 -0
- package/dist/tools/get-channel-info.d.ts +2 -0
- package/dist/tools/get-channel-info.d.ts.map +1 -1
- package/dist/tools/get-channel-info.js +8 -1
- package/dist/tools/get-channel-info.js.map +1 -1
- package/dist/tools/get-chapters.d.ts +2 -2
- package/dist/tools/get-comments.d.ts +2 -2
- package/dist/tools/get-playlist-info.d.ts.map +1 -1
- package/dist/tools/get-playlist-info.js +1 -0
- package/dist/tools/get-playlist-info.js.map +1 -1
- package/dist/tools/get-thumbnail.d.ts +38 -0
- package/dist/tools/get-thumbnail.d.ts.map +1 -0
- package/dist/tools/get-thumbnail.js +152 -0
- package/dist/tools/get-thumbnail.js.map +1 -0
- package/dist/tools/get-transcript.d.ts +2 -2
- package/dist/tools/get-transcript.d.ts.map +1 -1
- package/dist/tools/get-transcript.js +2 -14
- package/dist/tools/get-transcript.js.map +1 -1
- package/dist/tools/library.d.ts +9 -7
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +23 -7
- package/dist/tools/library.js.map +1 -1
- package/dist/tools/list-channel-thumbnails.d.ts +235 -0
- package/dist/tools/list-channel-thumbnails.d.ts.map +1 -0
- package/dist/tools/list-channel-thumbnails.js +79 -0
- package/dist/tools/list-channel-thumbnails.js.map +1 -0
- package/dist/tools/list-library.d.ts +4 -4
- package/dist/tools/manage-brain.d.ts +39 -0
- package/dist/tools/manage-brain.d.ts.map +1 -0
- package/dist/tools/manage-brain.js +53 -0
- package/dist/tools/manage-brain.js.map +1 -0
- package/dist/tools/save-to-library.d.ts.map +1 -1
- package/dist/tools/save-to-library.js +5 -1
- package/dist/tools/save-to-library.js.map +1 -1
- package/dist/tools/search-channels.d.ts +10 -4
- package/dist/tools/search-channels.d.ts.map +1 -1
- package/dist/tools/search-transcript.d.ts +2 -2
- package/dist/tools/search-transcript.d.ts.map +1 -1
- package/dist/tools/search-transcript.js +6 -13
- package/dist/tools/search-transcript.js.map +1 -1
- package/dist/tools/search-videos.d.ts +11 -8
- package/dist/tools/search-videos.d.ts.map +1 -1
- package/dist/utils/batches.d.ts +15 -0
- package/dist/utils/batches.d.ts.map +1 -0
- package/dist/utils/batches.js +31 -0
- package/dist/utils/batches.js.map +1 -0
- package/dist/utils/brain-build.d.ts +40 -0
- package/dist/utils/brain-build.d.ts.map +1 -0
- package/dist/utils/brain-build.js +200 -0
- package/dist/utils/brain-build.js.map +1 -0
- package/dist/utils/brain-chunks.d.ts +33 -0
- package/dist/utils/brain-chunks.d.ts.map +1 -0
- package/dist/utils/brain-chunks.js +87 -0
- package/dist/utils/brain-chunks.js.map +1 -0
- package/dist/utils/brain-index.d.ts +27 -0
- package/dist/utils/brain-index.d.ts.map +1 -0
- package/dist/utils/brain-index.js +101 -0
- package/dist/utils/brain-index.js.map +1 -0
- package/dist/utils/brain-ingest.d.ts +57 -0
- package/dist/utils/brain-ingest.d.ts.map +1 -0
- package/dist/utils/brain-ingest.js +127 -0
- package/dist/utils/brain-ingest.js.map +1 -0
- package/dist/utils/brain-lock.d.ts +4 -0
- package/dist/utils/brain-lock.d.ts.map +1 -0
- package/dist/utils/brain-lock.js +17 -0
- package/dist/utils/brain-lock.js.map +1 -0
- package/dist/utils/brain-lookup.d.ts +11 -0
- package/dist/utils/brain-lookup.d.ts.map +1 -0
- package/dist/utils/brain-lookup.js +36 -0
- package/dist/utils/brain-lookup.js.map +1 -0
- package/dist/utils/brain-paths.d.ts +19 -0
- package/dist/utils/brain-paths.d.ts.map +1 -0
- package/dist/utils/brain-paths.js +34 -0
- package/dist/utils/brain-paths.js.map +1 -0
- package/dist/utils/brain-phrases.d.ts +31 -0
- package/dist/utils/brain-phrases.d.ts.map +1 -0
- package/dist/utils/brain-phrases.js +116 -0
- package/dist/utils/brain-phrases.js.map +1 -0
- package/dist/utils/brain-stats.d.ts +25 -0
- package/dist/utils/brain-stats.d.ts.map +1 -0
- package/dist/utils/brain-stats.js +64 -0
- package/dist/utils/brain-stats.js.map +1 -0
- package/dist/utils/brain-storage.d.ts +28 -0
- package/dist/utils/brain-storage.d.ts.map +1 -0
- package/dist/utils/brain-storage.js +87 -0
- package/dist/utils/brain-storage.js.map +1 -0
- package/dist/utils/caption-probe.d.ts +7 -0
- package/dist/utils/caption-probe.d.ts.map +1 -0
- package/dist/utils/caption-probe.js +36 -0
- package/dist/utils/caption-probe.js.map +1 -0
- package/dist/utils/channel-images.d.ts +16 -0
- package/dist/utils/channel-images.d.ts.map +1 -0
- package/dist/utils/channel-images.js +35 -0
- package/dist/utils/channel-images.js.map +1 -0
- package/dist/utils/channel-lookup.d.ts +5 -0
- package/dist/utils/channel-lookup.d.ts.map +1 -0
- package/dist/utils/channel-lookup.js +37 -0
- package/dist/utils/channel-lookup.js.map +1 -0
- package/dist/utils/chapters.d.ts +11 -0
- package/dist/utils/chapters.d.ts.map +1 -0
- package/dist/utils/chapters.js +24 -0
- package/dist/utils/chapters.js.map +1 -0
- package/dist/utils/clips.d.ts.map +1 -1
- package/dist/utils/clips.js +22 -30
- package/dist/utils/clips.js.map +1 -1
- package/dist/utils/env.d.ts +26 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +72 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errors.d.ts +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +20 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/file-lock.d.ts +34 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +91 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/flat-listing.d.ts +89 -0
- package/dist/utils/flat-listing.d.ts.map +1 -0
- package/dist/utils/flat-listing.js +68 -0
- package/dist/utils/flat-listing.js.map +1 -0
- package/dist/utils/format.d.ts +1 -3
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +1 -5
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/guard.d.ts +21 -0
- package/dist/utils/guard.d.ts.map +1 -0
- package/dist/utils/guard.js +105 -0
- package/dist/utils/guard.js.map +1 -0
- package/dist/utils/image-dimensions.d.ts +19 -0
- package/dist/utils/image-dimensions.d.ts.map +1 -0
- package/dist/utils/image-dimensions.js +93 -0
- package/dist/utils/image-dimensions.js.map +1 -0
- package/dist/utils/image-fetch.d.ts +31 -0
- package/dist/utils/image-fetch.d.ts.map +1 -0
- package/dist/utils/image-fetch.js +141 -0
- package/dist/utils/image-fetch.js.map +1 -0
- package/dist/utils/json-file.d.ts +45 -0
- package/dist/utils/json-file.d.ts.map +1 -0
- package/dist/utils/json-file.js +60 -0
- package/dist/utils/json-file.js.map +1 -0
- package/dist/utils/paths.d.ts +19 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +27 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/pattern.d.ts +30 -0
- package/dist/utils/pattern.d.ts.map +1 -0
- package/dist/utils/pattern.js +130 -0
- package/dist/utils/pattern.js.map +1 -0
- package/dist/utils/search-index.d.ts +22 -7
- package/dist/utils/search-index.d.ts.map +1 -1
- package/dist/utils/search-index.js +26 -8
- package/dist/utils/search-index.js.map +1 -1
- package/dist/utils/storage.d.ts +14 -44
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js +47 -84
- package/dist/utils/storage.js.map +1 -1
- package/dist/utils/subtitles.d.ts +7 -0
- package/dist/utils/subtitles.d.ts.map +1 -0
- package/dist/utils/subtitles.js +30 -0
- package/dist/utils/subtitles.js.map +1 -0
- package/dist/utils/thumbnail-entry.d.ts +19 -0
- package/dist/utils/thumbnail-entry.d.ts.map +1 -0
- package/dist/utils/thumbnail-entry.js +119 -0
- package/dist/utils/thumbnail-entry.js.map +1 -0
- package/dist/utils/thumbnail-fetch.d.ts +37 -0
- package/dist/utils/thumbnail-fetch.d.ts.map +1 -0
- package/dist/utils/thumbnail-fetch.js +89 -0
- package/dist/utils/thumbnail-fetch.js.map +1 -0
- package/dist/utils/thumbnail-ladder.d.ts +44 -0
- package/dist/utils/thumbnail-ladder.d.ts.map +1 -0
- package/dist/utils/thumbnail-ladder.js +68 -0
- package/dist/utils/thumbnail-ladder.js.map +1 -0
- package/dist/utils/thumbnail-listing.d.ts +16 -0
- package/dist/utils/thumbnail-listing.d.ts.map +1 -0
- package/dist/utils/thumbnail-listing.js +26 -0
- package/dist/utils/thumbnail-listing.js.map +1 -0
- package/dist/utils/thumbnail-paths.d.ts +20 -0
- package/dist/utils/thumbnail-paths.d.ts.map +1 -0
- package/dist/utils/thumbnail-paths.js +35 -0
- package/dist/utils/thumbnail-paths.js.map +1 -0
- package/dist/utils/thumbnail-store.d.ts +19 -0
- package/dist/utils/thumbnail-store.d.ts.map +1 -0
- package/dist/utils/thumbnail-store.js +125 -0
- package/dist/utils/thumbnail-store.js.map +1 -0
- package/dist/utils/transcript-cache.d.ts +20 -0
- package/dist/utils/transcript-cache.d.ts.map +1 -0
- package/dist/utils/transcript-cache.js +127 -0
- package/dist/utils/transcript-cache.js.map +1 -0
- package/dist/utils/transcript-search.d.ts +20 -0
- package/dist/utils/transcript-search.d.ts.map +1 -0
- package/dist/utils/transcript-search.js +35 -0
- package/dist/utils/transcript-search.js.map +1 -0
- package/dist/utils/transcript.d.ts +14 -34
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +5 -64
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validate-youtube.d.ts +35 -0
- package/dist/utils/validate-youtube.d.ts.map +1 -0
- package/dist/utils/validate-youtube.js +87 -0
- package/dist/utils/validate-youtube.js.map +1 -0
- package/dist/utils/validate.d.ts +11 -3
- package/dist/utils/validate.d.ts.map +1 -1
- package/dist/utils/validate.js +43 -18
- package/dist/utils/validate.js.map +1 -1
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +19 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/utils/youtube-channel.d.ts +44 -0
- package/dist/utils/youtube-channel.d.ts.map +1 -0
- package/dist/utils/youtube-channel.js +61 -0
- package/dist/utils/youtube-channel.js.map +1 -0
- package/dist/utils/youtube-download.d.ts +27 -0
- package/dist/utils/youtube-download.d.ts.map +1 -0
- package/dist/utils/youtube-download.js +118 -0
- package/dist/utils/youtube-download.js.map +1 -0
- package/dist/utils/youtube-schemas.d.ts +394 -0
- package/dist/utils/youtube-schemas.d.ts.map +1 -0
- package/dist/utils/youtube-schemas.js +118 -0
- package/dist/utils/youtube-schemas.js.map +1 -0
- package/dist/utils/youtube-search.d.ts +14 -0
- package/dist/utils/youtube-search.d.ts.map +1 -0
- package/dist/utils/youtube-search.js +39 -0
- package/dist/utils/youtube-search.js.map +1 -0
- package/dist/utils/youtube-url.d.ts +25 -0
- package/dist/utils/youtube-url.d.ts.map +1 -0
- package/dist/utils/youtube-url.js +75 -0
- package/dist/utils/youtube-url.js.map +1 -0
- package/dist/utils/youtube-video.d.ts +47 -0
- package/dist/utils/youtube-video.d.ts.map +1 -0
- package/dist/utils/youtube-video.js +98 -0
- package/dist/utils/youtube-video.js.map +1 -0
- package/dist/utils/youtube.d.ts +13 -111
- package/dist/utils/youtube.d.ts.map +1 -1
- package/dist/utils/youtube.js +11 -480
- package/dist/utils/youtube.js.map +1 -1
- package/dist/utils/ytdlp-env.d.ts +33 -0
- package/dist/utils/ytdlp-env.d.ts.map +1 -0
- package/dist/utils/ytdlp-env.js +121 -0
- package/dist/utils/ytdlp-env.js.map +1 -0
- package/dist/utils/ytdlp-limiter.d.ts +24 -0
- package/dist/utils/ytdlp-limiter.d.ts.map +1 -0
- package/dist/utils/ytdlp-limiter.js +69 -0
- package/dist/utils/ytdlp-limiter.js.map +1 -0
- package/dist/utils/ytdlp-parse.d.ts +13 -0
- package/dist/utils/ytdlp-parse.d.ts.map +1 -0
- package/dist/utils/ytdlp-parse.js +48 -0
- package/dist/utils/ytdlp-parse.js.map +1 -0
- package/dist/utils/ytdlp.d.ts +13 -18
- package/dist/utils/ytdlp.d.ts.map +1 -1
- package/dist/utils/ytdlp.js +21 -110
- package/dist/utils/ytdlp.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { YouTubeError } from './errors.js';
|
|
2
|
+
import { assertYouTubeUrl, CHANNEL_ID_PATTERN, VIDEO_ID_PATTERN } from './validate-youtube.js';
|
|
3
|
+
/**
|
|
4
|
+
* Video ids, watch URLs and the duration formatter every YouTube module shares.
|
|
5
|
+
*
|
|
6
|
+
* Split out of youtube.ts so the modules that read video, channel, download
|
|
7
|
+
* and transcript data can each depend on this without depending on each other.
|
|
8
|
+
*/
|
|
9
|
+
export function extractVideoId(urlOrId) {
|
|
10
|
+
// If it's already an ID (11 characters, no special chars except - and _)
|
|
11
|
+
if (VIDEO_ID_PATTERN.test(urlOrId)) {
|
|
12
|
+
return urlOrId;
|
|
13
|
+
}
|
|
14
|
+
// Try to extract from URL
|
|
15
|
+
const patterns = [
|
|
16
|
+
/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/)([a-zA-Z0-9_-]{11})/,
|
|
17
|
+
/(?:youtube\.com\/shorts\/)([a-zA-Z0-9_-]{11})/,
|
|
18
|
+
];
|
|
19
|
+
for (const pattern of patterns) {
|
|
20
|
+
const match = pattern.exec(urlOrId);
|
|
21
|
+
if (match?.[1] !== undefined) {
|
|
22
|
+
return match[1];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Truncated: the value is model-controlled and could be arbitrarily long.
|
|
26
|
+
const shown = urlOrId.length > 64 ? `${urlOrId.slice(0, 61)}...` : urlOrId;
|
|
27
|
+
throw new YouTubeError('INVALID_INPUT', `Could not extract video ID from: ${shown}`, {
|
|
28
|
+
nextStep: 'Pass an 11-character video id or a youtube.com / youtu.be watch URL.',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const HANDLE_PATTERN = /^@[\w.-]{1,50}$/;
|
|
32
|
+
/**
|
|
33
|
+
* Turn a caller-supplied playlist or channel reference into a yt-dlp target.
|
|
34
|
+
*
|
|
35
|
+
* Three shapes are accepted — a URL on a YouTube host, an `@handle`, or a bare
|
|
36
|
+
* channel id — and everything else is refused. This is the boundary that keeps
|
|
37
|
+
* `fetch_videos` and friends from pointing yt-dlp at an arbitrary host.
|
|
38
|
+
*/
|
|
39
|
+
export function resolveListTarget(input) {
|
|
40
|
+
const trimmed = input.trim();
|
|
41
|
+
if (HANDLE_PATTERN.test(trimmed))
|
|
42
|
+
return `https://www.youtube.com/${trimmed}`;
|
|
43
|
+
if (CHANNEL_ID_PATTERN.test(trimmed))
|
|
44
|
+
return `https://www.youtube.com/channel/${trimmed}`;
|
|
45
|
+
if (trimmed.includes('/') || trimmed.includes('.'))
|
|
46
|
+
return assertYouTubeUrl(trimmed);
|
|
47
|
+
throw new YouTubeError('INVALID_INPUT', `"${trimmed.slice(0, 64)}" is not a playlist or channel.`, {
|
|
48
|
+
nextStep: 'Pass a YouTube playlist or channel URL, an @handle, or a channel id.',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The URL for a channel named any way a caller might name it: a URL (checked),
|
|
53
|
+
* an `@handle`, or a bare name treated as a handle, which is what
|
|
54
|
+
* `get_channel_info` has always done.
|
|
55
|
+
*/
|
|
56
|
+
export function channelUrlFor(channel) {
|
|
57
|
+
const trimmed = channel.trim();
|
|
58
|
+
if (trimmed.includes('/') || trimmed.includes('://'))
|
|
59
|
+
return assertYouTubeUrl(trimmed);
|
|
60
|
+
return `https://www.youtube.com/${trimmed.startsWith('@') ? trimmed : `@${trimmed}`}`;
|
|
61
|
+
}
|
|
62
|
+
/** The canonical watch page for a video id. */
|
|
63
|
+
export function watchUrl(videoId) {
|
|
64
|
+
return `https://www.youtube.com/watch?v=${videoId}`;
|
|
65
|
+
}
|
|
66
|
+
export function formatDuration(seconds) {
|
|
67
|
+
const hours = Math.floor(seconds / 3600);
|
|
68
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
69
|
+
const secs = seconds % 60;
|
|
70
|
+
if (hours > 0) {
|
|
71
|
+
return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
|
72
|
+
}
|
|
73
|
+
return `${minutes}:${secs.toString().padStart(2, '0')}`;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=youtube-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-url.js","sourceRoot":"","sources":["../../src/utils/youtube-url.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Everything read about one video: metadata, chapters and comments. */
|
|
2
|
+
export interface VideoInfo {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
channel: string;
|
|
6
|
+
duration: number;
|
|
7
|
+
durationFormatted: string;
|
|
8
|
+
uploadDate: string;
|
|
9
|
+
description: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
url: string;
|
|
12
|
+
thumbnailUrl: string;
|
|
13
|
+
viewCount: number;
|
|
14
|
+
likeCount: number;
|
|
15
|
+
commentCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Chapter {
|
|
18
|
+
title: string;
|
|
19
|
+
startTime: number;
|
|
20
|
+
startTimeFormatted: string;
|
|
21
|
+
endTime: number;
|
|
22
|
+
endTimeFormatted: string;
|
|
23
|
+
}
|
|
24
|
+
export interface VideoComment {
|
|
25
|
+
author: string;
|
|
26
|
+
text: string;
|
|
27
|
+
likeCount: number;
|
|
28
|
+
isPinned: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function getVideoInfo(urlOrId: string): Promise<VideoInfo>;
|
|
31
|
+
export declare function getChapters(urlOrId: string): Promise<Chapter[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Publication date, length and chapters, from a single metadata fetch.
|
|
34
|
+
*
|
|
35
|
+
* Reading a channel needs all three per video, and asking for them separately
|
|
36
|
+
* spawns yt-dlp twice for one identical `-j` request — doubling the requests a
|
|
37
|
+
* build makes to YouTube, which is the thing most likely to get it throttled.
|
|
38
|
+
* `getChapters` is the same call with everything but the chapters discarded.
|
|
39
|
+
*/
|
|
40
|
+
export interface VideoDetails {
|
|
41
|
+
uploadDate: string;
|
|
42
|
+
durationSeconds: number;
|
|
43
|
+
chapters: Chapter[];
|
|
44
|
+
}
|
|
45
|
+
export declare function getVideoDetails(urlOrId: string): Promise<VideoDetails>;
|
|
46
|
+
export declare function getComments(urlOrId: string, limit?: number): Promise<VideoComment[]>;
|
|
47
|
+
//# sourceMappingURL=youtube-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-video.d.ts","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"AAMA,wEAAwE;AAExE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAoDtE;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAErE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB5E;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BtF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { formatYouTubeDate } from './format.js';
|
|
2
|
+
import { classifyPlayability } from './errors.js';
|
|
3
|
+
import { TIMEOUTS, parseYtDlpJson, runYtDlp } from './ytdlp.js';
|
|
4
|
+
import { commentsRowSchema, videoDetailsRowSchema, videoInfoRowSchema } from './youtube-schemas.js';
|
|
5
|
+
import { extractVideoId, formatDuration, watchUrl } from './youtube-url.js';
|
|
6
|
+
const VIDEO_INFO_TEMPLATE = '%(.{id,title,channel,duration,upload_date,description,tags,thumbnail,view_count,like_count,comment_count,availability,live_status})j';
|
|
7
|
+
export async function getVideoInfo(urlOrId) {
|
|
8
|
+
const videoId = extractVideoId(urlOrId);
|
|
9
|
+
const url = watchUrl(videoId);
|
|
10
|
+
const stdout = await runYtDlp([
|
|
11
|
+
'--skip-download',
|
|
12
|
+
// Without this, a video YouTube refuses to serve aborts extraction and the
|
|
13
|
+
// only thing left to read is YouTube's localised refusal text. With it,
|
|
14
|
+
// yt-dlp downgrades that abort to a warning and still fills in the
|
|
15
|
+
// structured fields, so the reason can be read from `availability` and
|
|
16
|
+
// `live_status` instead of guessed at from prose.
|
|
17
|
+
'--ignore-no-formats-error',
|
|
18
|
+
// One JSON object with exactly these fields, rather than a delimited row:
|
|
19
|
+
// yt-dlp writes `null` for what it does not know, the parser checks each
|
|
20
|
+
// field's type, and a description containing the delimiter cannot shift
|
|
21
|
+
// every field after it.
|
|
22
|
+
'--print',
|
|
23
|
+
VIDEO_INFO_TEMPLATE,
|
|
24
|
+
], { label: 'get_video_info', target: url });
|
|
25
|
+
const row = parseYtDlpJson(stdout, videoInfoRowSchema, 'video metadata');
|
|
26
|
+
// Refusals reach us as a populated row rather than a failure, so this is the
|
|
27
|
+
// point at which one becomes a typed error.
|
|
28
|
+
const refusal = classifyPlayability({
|
|
29
|
+
availability: row.availability ?? undefined,
|
|
30
|
+
liveStatus: row.live_status ?? undefined,
|
|
31
|
+
});
|
|
32
|
+
if (refusal)
|
|
33
|
+
throw refusal;
|
|
34
|
+
const duration = row.duration ?? 0;
|
|
35
|
+
return {
|
|
36
|
+
id: row.id ?? videoId,
|
|
37
|
+
title: row.title ?? '',
|
|
38
|
+
channel: row.channel ?? '',
|
|
39
|
+
duration,
|
|
40
|
+
durationFormatted: formatDuration(duration),
|
|
41
|
+
uploadDate: formatYouTubeDate(row.upload_date ?? ''),
|
|
42
|
+
description: row.description ?? '',
|
|
43
|
+
tags: Array.isArray(row.tags)
|
|
44
|
+
? row.tags.filter((tag) => typeof tag === 'string')
|
|
45
|
+
: [],
|
|
46
|
+
url,
|
|
47
|
+
thumbnailUrl: row.thumbnail ?? '',
|
|
48
|
+
viewCount: row.view_count ?? 0,
|
|
49
|
+
likeCount: row.like_count ?? 0,
|
|
50
|
+
commentCount: row.comment_count ?? 0,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export async function getChapters(urlOrId) {
|
|
54
|
+
return (await getVideoDetails(urlOrId)).chapters;
|
|
55
|
+
}
|
|
56
|
+
export async function getVideoDetails(urlOrId) {
|
|
57
|
+
const videoId = extractVideoId(urlOrId);
|
|
58
|
+
const url = watchUrl(videoId);
|
|
59
|
+
const stdout = await runYtDlp(['-j', '--skip-download'], {
|
|
60
|
+
label: 'get_video_details',
|
|
61
|
+
target: url,
|
|
62
|
+
});
|
|
63
|
+
const data = parseYtDlpJson(stdout, videoDetailsRowSchema, 'video details');
|
|
64
|
+
return {
|
|
65
|
+
uploadDate: formatYouTubeDate(data.upload_date ?? ''),
|
|
66
|
+
durationSeconds: typeof data.duration === 'number' ? data.duration : 0,
|
|
67
|
+
chapters: (data.chapters ?? []).map((ch) => ({
|
|
68
|
+
title: ch.title,
|
|
69
|
+
startTime: ch.start_time,
|
|
70
|
+
startTimeFormatted: formatDuration(Math.floor(ch.start_time)),
|
|
71
|
+
endTime: ch.end_time,
|
|
72
|
+
endTimeFormatted: formatDuration(Math.floor(ch.end_time)),
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export async function getComments(urlOrId, limit = 20) {
|
|
77
|
+
const videoId = extractVideoId(urlOrId);
|
|
78
|
+
const url = watchUrl(videoId);
|
|
79
|
+
const stdout = await runYtDlp([
|
|
80
|
+
'-j',
|
|
81
|
+
'--skip-download',
|
|
82
|
+
'--write-comments',
|
|
83
|
+
'--extractor-args',
|
|
84
|
+
`youtube:comment_sort=top;max_comments=${limit}`,
|
|
85
|
+
], { label: 'get_comments', timeoutMs: TIMEOUTS.comments, target: url });
|
|
86
|
+
const data = parseYtDlpJson(stdout, commentsRowSchema, 'video comments');
|
|
87
|
+
const comments = data.comments ?? [];
|
|
88
|
+
return comments
|
|
89
|
+
.filter((c) => c.parent === 'root')
|
|
90
|
+
.slice(0, limit)
|
|
91
|
+
.map((c) => ({
|
|
92
|
+
author: c.author ?? 'Unknown',
|
|
93
|
+
text: c.text ?? '',
|
|
94
|
+
likeCount: c.like_count ?? 0,
|
|
95
|
+
isPinned: c.is_pinned ?? false,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=youtube-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube-video.js","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/youtube.d.ts
CHANGED
|
@@ -1,112 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
likeCount: number;
|
|
15
|
-
commentCount: number;
|
|
16
|
-
}
|
|
17
|
-
export interface VideoListItem {
|
|
18
|
-
id: string;
|
|
19
|
-
title: string;
|
|
20
|
-
duration: number;
|
|
21
|
-
durationFormatted: string;
|
|
22
|
-
uploadDate: string;
|
|
23
|
-
url: string;
|
|
24
|
-
}
|
|
25
|
-
export interface TranscriptResult {
|
|
26
|
-
/** The whole transcript as plain text, unchanged from previous releases. */
|
|
27
|
-
transcript: string;
|
|
28
|
-
/** The same content with cue timings preserved. */
|
|
29
|
-
segments: TranscriptSegment[];
|
|
30
|
-
language: string;
|
|
31
|
-
videoId: string;
|
|
32
|
-
/** True when served from the local cache rather than refetched. */
|
|
33
|
-
cached: boolean;
|
|
34
|
-
}
|
|
35
|
-
export interface VideoFormat {
|
|
36
|
-
formatId: string;
|
|
37
|
-
ext: string;
|
|
38
|
-
resolution: string;
|
|
39
|
-
fps?: number;
|
|
40
|
-
vcodec: string;
|
|
41
|
-
acodec: string;
|
|
42
|
-
filesize?: number;
|
|
43
|
-
note: string;
|
|
44
|
-
}
|
|
45
|
-
export interface DownloadResult {
|
|
46
|
-
videoId: string;
|
|
47
|
-
title: string;
|
|
48
|
-
filePath: string;
|
|
49
|
-
format: string;
|
|
50
|
-
}
|
|
51
|
-
export interface SearchResult {
|
|
52
|
-
id: string;
|
|
53
|
-
title: string;
|
|
54
|
-
duration: number;
|
|
55
|
-
durationFormatted: string;
|
|
56
|
-
channel: string;
|
|
57
|
-
viewCount: number;
|
|
58
|
-
url: string;
|
|
59
|
-
}
|
|
60
|
-
export interface Chapter {
|
|
61
|
-
title: string;
|
|
62
|
-
startTime: number;
|
|
63
|
-
startTimeFormatted: string;
|
|
64
|
-
endTime: number;
|
|
65
|
-
endTimeFormatted: string;
|
|
66
|
-
}
|
|
67
|
-
export interface VideoComment {
|
|
68
|
-
author: string;
|
|
69
|
-
text: string;
|
|
70
|
-
likeCount: number;
|
|
71
|
-
isPinned: boolean;
|
|
72
|
-
}
|
|
73
|
-
export interface ChannelInfo {
|
|
74
|
-
name: string;
|
|
75
|
-
channelId: string;
|
|
76
|
-
handle: string;
|
|
77
|
-
subscriberCount: number;
|
|
78
|
-
channelUrl: string;
|
|
79
|
-
description: string;
|
|
80
|
-
}
|
|
81
|
-
export interface PlaylistInfo {
|
|
82
|
-
id: string;
|
|
83
|
-
title: string;
|
|
84
|
-
channel: string;
|
|
85
|
-
handle: string;
|
|
86
|
-
channelUrl: string;
|
|
87
|
-
videoCount: number;
|
|
88
|
-
lastModified: string;
|
|
89
|
-
url: string;
|
|
90
|
-
description: string;
|
|
91
|
-
}
|
|
92
|
-
export declare function extractVideoId(urlOrId: string): string;
|
|
93
|
-
export declare function getVideoInfo(urlOrId: string): Promise<VideoInfo>;
|
|
94
|
-
export declare function listVideos(urlOrChannel: string, limit?: number): Promise<VideoListItem[]>;
|
|
95
|
-
export interface GetTranscriptOptions {
|
|
96
|
-
language?: string;
|
|
97
|
-
/** Ignore any cached copy and refetch from YouTube. */
|
|
98
|
-
refresh?: boolean;
|
|
99
|
-
}
|
|
100
|
-
/** True when a usable transcript is already on disk, in any language. */
|
|
101
|
-
export declare function hasCachedTranscript(videoId: string): boolean;
|
|
102
|
-
export declare function getTranscript(urlOrId: string, preferredLangOrOptions?: string | GetTranscriptOptions): Promise<TranscriptResult>;
|
|
103
|
-
export declare function listFormats(urlOrId: string): Promise<VideoFormat[]>;
|
|
104
|
-
export type VideoQuality = 'best' | '2160p' | '1440p' | '1080p' | '720p' | '480p' | '360p' | 'audio';
|
|
105
|
-
export declare function downloadVideo(urlOrId: string, formatId: string, outputDir?: string, quality?: VideoQuality): Promise<DownloadResult>;
|
|
106
|
-
export declare function searchVideos(query: string, limit?: number): Promise<SearchResult[]>;
|
|
107
|
-
export declare function getChapters(urlOrId: string): Promise<Chapter[]>;
|
|
108
|
-
export declare function getComments(urlOrId: string, limit?: number): Promise<VideoComment[]>;
|
|
109
|
-
export declare function searchChannels(query: string, limit?: number): Promise<ChannelInfo[]>;
|
|
110
|
-
export declare function getPlaylistInfo(playlistUrl: string): Promise<PlaylistInfo>;
|
|
111
|
-
export declare function getChannelInfo(channel: string): Promise<ChannelInfo>;
|
|
1
|
+
/**
|
|
2
|
+
* Everything the server knows how to ask YouTube.
|
|
3
|
+
*
|
|
4
|
+
* This is a barrel: the implementation lives in one module per concern so each
|
|
5
|
+
* stays small enough to hold in view. Consumers import from here, so a module
|
|
6
|
+
* can move without every tool and test that uses it having to follow.
|
|
7
|
+
*/
|
|
8
|
+
export * from './youtube-url.js';
|
|
9
|
+
export * from './youtube-video.js';
|
|
10
|
+
export * from './youtube-channel.js';
|
|
11
|
+
export * from './youtube-search.js';
|
|
12
|
+
export * from './youtube-download.js';
|
|
13
|
+
export * from './transcript-cache.js';
|
|
112
14
|
//# sourceMappingURL=youtube.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"youtube.d.ts","sourceRoot":"","sources":["../../src/utils/youtube.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"youtube.d.ts","sourceRoot":"","sources":["../../src/utils/youtube.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|