@ooneex/youtube 0.0.18 → 1.0.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 +54 -0
- package/dist/index.d.ts +2 -417
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1 +1,55 @@
|
|
|
1
1
|
# @ooneex/youtube
|
|
2
|
+
|
|
3
|
+
YouTube video downloader and metadata extraction library for fetching video information, thumbnails, and media streams.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
✅ **Video ID Extraction** - Parse video IDs from watch URLs, short URLs, embed URLs, and other YouTube URL formats
|
|
12
|
+
|
|
13
|
+
✅ **Embed URL Generation** - Convert any YouTube URL or video ID into an embeddable URL via `getEmbedUrl`
|
|
14
|
+
|
|
15
|
+
✅ **Watch URL Generation** - Convert any YouTube URL or video ID into a standard watch URL via `getWatchUrl`
|
|
16
|
+
|
|
17
|
+
✅ **ytdlp Integration** - Type definitions for ytdlp-nodejs including video/audio quality, format options, and download progress
|
|
18
|
+
|
|
19
|
+
✅ **Quality Types** - `YoutubeVideoQualityType` (144p to 2160p) and `YoutubeAudioQualityType` for stream selection
|
|
20
|
+
|
|
21
|
+
✅ **Error Handling** - Custom `YoutubeException` for YouTube-specific error scenarios
|
|
22
|
+
|
|
23
|
+
✅ **Type-Safe** - Full TypeScript support with `IYoutube` interface and re-exported ytdlp types
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun add @ooneex/youtube
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
34
|
+
|
|
35
|
+
## Contributing
|
|
36
|
+
|
|
37
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
38
|
+
|
|
39
|
+
### Development Setup
|
|
40
|
+
|
|
41
|
+
1. Clone the repository
|
|
42
|
+
2. Install dependencies: `bun install`
|
|
43
|
+
3. Run tests: `bun run test`
|
|
44
|
+
4. Build the project: `bun run build`
|
|
45
|
+
|
|
46
|
+
### Guidelines
|
|
47
|
+
|
|
48
|
+
- Write tests for new features
|
|
49
|
+
- Follow the existing code style
|
|
50
|
+
- Update documentation for API changes
|
|
51
|
+
- Ensure all tests pass before submitting PR
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
Made with ❤️ by the Ooneex team
|
package/dist/index.d.ts
CHANGED
|
@@ -1,433 +1,18 @@
|
|
|
1
|
-
import { ArgsOptions, FormatOptions,
|
|
2
|
-
/**
|
|
3
|
-
* Video information returned from YouTube.
|
|
4
|
-
* Contains metadata such as title, description, duration, view count, etc.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* const info: YoutubeVideoInfoType = await youtube.getVideoInfo(url);
|
|
9
|
-
* console.log(info.title, info.duration, info.view_count);
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
type YoutubeVideoInfoType = VideoInfo;
|
|
13
|
-
/**
|
|
14
|
-
* Playlist information returned from YouTube.
|
|
15
|
-
* Contains playlist metadata and list of videos in the playlist.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* const playlist: YoutubePlaylistInfoType = await youtube.getPlaylistInfo(url);
|
|
20
|
-
* console.log(playlist.title, playlist.entries.length);
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
type YoutubePlaylistInfoType = PlaylistInfo;
|
|
24
|
-
/**
|
|
25
|
-
* Video format information including codec, resolution, and bitrate details.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```typescript
|
|
29
|
-
* const info = await youtube.getVideoInfo(url);
|
|
30
|
-
* const formats: YoutubeVideoFormatType[] = info.formats;
|
|
31
|
-
* formats.forEach(f => console.log(f.format_id, f.ext, f.resolution));
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
1
|
+
import { ArgsOptions, FormatOptions, QualityOptions, VideoFormat, VideoProgress } from "ytdlp-nodejs";
|
|
34
2
|
type YoutubeVideoFormatType = VideoFormat;
|
|
35
|
-
/**
|
|
36
|
-
* Download progress information for tracking video download status.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const progress: YoutubeVideoProgressType = {
|
|
41
|
-
* percent: 50,
|
|
42
|
-
* totalSize: "100MB",
|
|
43
|
-
* currentSpeed: "5MB/s",
|
|
44
|
-
* eta: "10s",
|
|
45
|
-
* };
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
3
|
type YoutubeVideoProgressType = VideoProgress;
|
|
49
|
-
/**
|
|
50
|
-
* Additional arguments options for yt-dlp commands.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```typescript
|
|
54
|
-
* const args: YoutubeArgsOptionsType = {
|
|
55
|
-
* noPlaylist: true,
|
|
56
|
-
* extractAudio: true,
|
|
57
|
-
* };
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
4
|
type YoutubeArgsOptionsType = ArgsOptions;
|
|
61
|
-
/**
|
|
62
|
-
* Format options for downloading videos with specific quality settings.
|
|
63
|
-
*
|
|
64
|
-
* @typeParam F - The format keyword type (e.g., "video", "audio", "videoandaudio")
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```typescript
|
|
68
|
-
* const options: YoutubeFormatOptionsType<"video"> = {
|
|
69
|
-
* format: { quality: "1080p" },
|
|
70
|
-
* };
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
5
|
type YoutubeFormatOptionsType<F extends YoutubeFormatKeyWordType> = FormatOptions<F>;
|
|
74
|
-
/**
|
|
75
|
-
* Quality options for specifying video/audio quality preferences.
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* const quality: YoutubeQualityOptionsType = {
|
|
80
|
-
* video: "1080p",
|
|
81
|
-
* audio: "highest",
|
|
82
|
-
* };
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
6
|
type YoutubeQualityOptionsType = QualityOptions;
|
|
86
|
-
/**
|
|
87
|
-
* Format keyword type for specifying download format categories.
|
|
88
|
-
* Can be "video", "audio", or "videoandaudio".
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```typescript
|
|
92
|
-
* const format: YoutubeFormatKeyWordType = "videoandaudio";
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
7
|
type YoutubeFormatKeyWordType = keyof QualityOptions;
|
|
96
|
-
/**
|
|
97
|
-
* Video quality presets for download operations.
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* ```typescript
|
|
101
|
-
* const quality: YoutubeVideoQualityType = "1080p";
|
|
102
|
-
*
|
|
103
|
-
* // Available options:
|
|
104
|
-
* // - "2160p" (4K)
|
|
105
|
-
* // - "1440p" (2K)
|
|
106
|
-
* // - "1080p" (Full HD)
|
|
107
|
-
* // - "720p" (HD)
|
|
108
|
-
* // - "480p" (SD)
|
|
109
|
-
* // - "360p", "240p", "144p" (Low quality)
|
|
110
|
-
* // - "highest" (Best available)
|
|
111
|
-
* // - "lowest" (Smallest file size)
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
8
|
type YoutubeVideoQualityType = "2160p" | "1440p" | "1080p" | "720p" | "480p" | "360p" | "240p" | "144p" | "highest" | "lowest";
|
|
115
|
-
/**
|
|
116
|
-
* Audio quality presets for audio download operations.
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* const quality: YoutubeAudioQualityType = "highest";
|
|
121
|
-
*
|
|
122
|
-
* // Available options:
|
|
123
|
-
* // - "highest" (Best available audio quality)
|
|
124
|
-
* // - "lowest" (Smallest file size)
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
9
|
type YoutubeAudioQualityType = "highest" | "lowest";
|
|
128
|
-
/**
|
|
129
|
-
* Configuration options for the YouTube client.
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```typescript
|
|
133
|
-
* const options: YoutubeOptionsType = {
|
|
134
|
-
* binaryPath: "/usr/local/bin/yt-dlp",
|
|
135
|
-
* ffmpegPath: "/usr/local/bin/ffmpeg",
|
|
136
|
-
* };
|
|
137
|
-
* const youtube = new Youtube(options);
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
type YoutubeOptionsType = {
|
|
141
|
-
/**
|
|
142
|
-
* Path to the yt-dlp binary.
|
|
143
|
-
* Falls back to YOUTUBE_YTDLP_PATH environment variable if not provided.
|
|
144
|
-
*/
|
|
145
|
-
binaryPath?: string;
|
|
146
|
-
/**
|
|
147
|
-
* Path to the ffmpeg binary.
|
|
148
|
-
* Falls back to YOUTUBE_FFMPEG_PATH environment variable if not provided.
|
|
149
|
-
*/
|
|
150
|
-
ffmpegPath?: string;
|
|
151
|
-
};
|
|
152
|
-
/**
|
|
153
|
-
* Interface defining the YouTube client API.
|
|
154
|
-
* Provides methods for fetching video info, downloading, and managing media.
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* class MyYoutubeClient implements IYoutube {
|
|
159
|
-
* async getVideoInfo(url: string) { ... }
|
|
160
|
-
* async getPlaylistInfo(url: string) { ... }
|
|
161
|
-
* // ... implement all methods
|
|
162
|
-
* }
|
|
163
|
-
* ```
|
|
164
|
-
*/
|
|
165
10
|
interface IYoutube {
|
|
166
|
-
/**
|
|
167
|
-
* Retrieves detailed information about a YouTube video.
|
|
168
|
-
* @param url - The YouTube video URL
|
|
169
|
-
* @returns Promise resolving to video metadata
|
|
170
|
-
*/
|
|
171
|
-
getVideoInfo(url: string): Promise<YoutubeVideoInfoType>;
|
|
172
|
-
/**
|
|
173
|
-
* Retrieves information about a YouTube playlist.
|
|
174
|
-
* @param url - The YouTube playlist URL
|
|
175
|
-
* @returns Promise resolving to playlist metadata
|
|
176
|
-
*/
|
|
177
|
-
getPlaylistInfo(url: string): Promise<YoutubePlaylistInfoType>;
|
|
178
|
-
/**
|
|
179
|
-
* Downloads a video to the local filesystem.
|
|
180
|
-
* @param url - The YouTube video URL
|
|
181
|
-
* @param destination - The destination path for the downloaded file
|
|
182
|
-
* @returns Promise resolving to the downloaded file path
|
|
183
|
-
*/
|
|
184
|
-
download(url: string, destination: string): Promise<string>;
|
|
185
|
-
/**
|
|
186
|
-
* Downloads a video and returns it as a File object.
|
|
187
|
-
* @param url - The YouTube video URL
|
|
188
|
-
* @param options - Optional filename and format settings
|
|
189
|
-
* @returns Promise resolving to a File object
|
|
190
|
-
*/
|
|
191
|
-
getFile<F extends YoutubeFormatKeyWordType>(url: string, options?: {
|
|
192
|
-
filename?: string;
|
|
193
|
-
format?: YoutubeFormatOptionsType<F>["format"];
|
|
194
|
-
}): Promise<File>;
|
|
195
|
-
/**
|
|
196
|
-
* Extracts the video ID (watch ID) from a YouTube URL.
|
|
197
|
-
* @param url - The YouTube video URL
|
|
198
|
-
* @returns The video ID or null if not found
|
|
199
|
-
*/
|
|
200
11
|
getWatchId(url: string): string | null;
|
|
201
|
-
/**
|
|
202
|
-
* Generates an embed URL for a YouTube video.
|
|
203
|
-
* @param urlOrId - The YouTube video URL or video ID
|
|
204
|
-
* @returns The embed URL or null if the video ID cannot be extracted
|
|
205
|
-
*/
|
|
206
12
|
getEmbedUrl(urlOrId: string): string | null;
|
|
207
|
-
/**
|
|
208
|
-
* Generates a standard watch URL for a YouTube video.
|
|
209
|
-
* @param urlOrId - The YouTube video URL or video ID
|
|
210
|
-
* @returns The watch URL or null if the video ID cannot be extracted
|
|
211
|
-
*/
|
|
212
13
|
getWatchUrl(urlOrId: string): string | null;
|
|
213
|
-
/**
|
|
214
|
-
* Downloads only the audio from a YouTube video.
|
|
215
|
-
* @param url - The YouTube video URL
|
|
216
|
-
* @param destination - The destination path for the downloaded audio file
|
|
217
|
-
* @returns Promise resolving to the downloaded audio file path
|
|
218
|
-
*/
|
|
219
|
-
downloadAudio(url: string, destination: string): Promise<string>;
|
|
220
14
|
}
|
|
221
|
-
/**
|
|
222
|
-
* YouTube client for downloading and extracting information from YouTube videos and playlists.
|
|
223
|
-
* Wraps yt-dlp functionality with a clean async API and proper error handling.
|
|
224
|
-
*
|
|
225
|
-
* @example Basic Usage
|
|
226
|
-
* ```typescript
|
|
227
|
-
* import { Youtube } from "@ooneex/youtube";
|
|
228
|
-
*
|
|
229
|
-
* const youtube = new Youtube();
|
|
230
|
-
*
|
|
231
|
-
* // Get video information
|
|
232
|
-
* const info = await youtube.getVideoInfo("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
233
|
-
* console.log(info.title, info.duration);
|
|
234
|
-
*
|
|
235
|
-
* // Download a video
|
|
236
|
-
* const filePath = await youtube.download("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
237
|
-
* console.log(`Downloaded to: ${filePath}`);
|
|
238
|
-
* ```
|
|
239
|
-
*
|
|
240
|
-
* @example Download with Quality Options
|
|
241
|
-
* ```typescript
|
|
242
|
-
* const youtube = new Youtube();
|
|
243
|
-
*
|
|
244
|
-
* // Download video in 1080p
|
|
245
|
-
* const path = await youtube.download(url, {
|
|
246
|
-
* format: { video: "1080p" },
|
|
247
|
-
* });
|
|
248
|
-
*
|
|
249
|
-
* // Download audio only
|
|
250
|
-
* const audioPath = await youtube.download(url, {
|
|
251
|
-
* format: { audio: "highest" },
|
|
252
|
-
* });
|
|
253
|
-
* ```
|
|
254
|
-
*/
|
|
255
15
|
declare class Youtube implements IYoutube {
|
|
256
|
-
private readonly ytdlp;
|
|
257
|
-
/**
|
|
258
|
-
* Creates a new YouTube client instance.
|
|
259
|
-
*
|
|
260
|
-
* @param options - Optional configuration for binary paths
|
|
261
|
-
* @throws {YoutubeException} If required binary paths are not configured
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```typescript
|
|
265
|
-
* const youtube = new Youtube();
|
|
266
|
-
* ```
|
|
267
|
-
*
|
|
268
|
-
* @example With Custom Paths
|
|
269
|
-
* ```typescript
|
|
270
|
-
* const youtube = new Youtube({
|
|
271
|
-
* binaryPath: "/custom/path/to/yt-dlp",
|
|
272
|
-
* ffmpegPath: "/custom/path/to/ffmpeg",
|
|
273
|
-
* });
|
|
274
|
-
* ```
|
|
275
|
-
*/
|
|
276
|
-
constructor(options?: YoutubeOptionsType);
|
|
277
|
-
/**
|
|
278
|
-
* Retrieves detailed metadata for a YouTube video.
|
|
279
|
-
*
|
|
280
|
-
* @param url - The YouTube video URL
|
|
281
|
-
* @returns Promise resolving to video information including title, description,
|
|
282
|
-
* duration, view count, available formats, and more
|
|
283
|
-
* @throws {YoutubeException} If the video cannot be accessed or URL is invalid
|
|
284
|
-
*
|
|
285
|
-
* @example
|
|
286
|
-
* ```typescript
|
|
287
|
-
* const youtube = new Youtube();
|
|
288
|
-
* const info = await youtube.getVideoInfo("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
289
|
-
*
|
|
290
|
-
* console.log("Title:", info.title);
|
|
291
|
-
* console.log("Duration:", info.duration, "seconds");
|
|
292
|
-
* console.log("Views:", info.view_count);
|
|
293
|
-
* console.log("Description:", info.description);
|
|
294
|
-
* console.log("Available formats:", info.formats.length);
|
|
295
|
-
* ```
|
|
296
|
-
*/
|
|
297
|
-
getVideoInfo(url: string): Promise<YoutubeVideoInfoType>;
|
|
298
|
-
/**
|
|
299
|
-
* Retrieves information about a YouTube playlist including all videos.
|
|
300
|
-
*
|
|
301
|
-
* @param url - The YouTube playlist URL
|
|
302
|
-
* @returns Promise resolving to playlist metadata and video entries
|
|
303
|
-
* @throws {YoutubeException} If the playlist cannot be accessed or URL is invalid
|
|
304
|
-
*
|
|
305
|
-
* @example
|
|
306
|
-
* ```typescript
|
|
307
|
-
* const youtube = new Youtube();
|
|
308
|
-
* const playlist = await youtube.getPlaylistInfo(
|
|
309
|
-
* "https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf"
|
|
310
|
-
* );
|
|
311
|
-
*
|
|
312
|
-
* console.log("Playlist:", playlist.title);
|
|
313
|
-
* console.log("Video count:", playlist.entries.length);
|
|
314
|
-
*
|
|
315
|
-
* // Iterate over videos in the playlist
|
|
316
|
-
* for (const video of playlist.entries) {
|
|
317
|
-
* console.log(`- ${video.title} (${video.duration}s)`);
|
|
318
|
-
* }
|
|
319
|
-
* ```
|
|
320
|
-
*/
|
|
321
|
-
getPlaylistInfo(url: string): Promise<YoutubePlaylistInfoType>;
|
|
322
|
-
/**
|
|
323
|
-
* Downloads a video to the local filesystem.
|
|
324
|
-
*
|
|
325
|
-
* @typeParam F - The format keyword type (video, audio, or videoandaudio)
|
|
326
|
-
* @param url - The YouTube video URL
|
|
327
|
-
* @param options - Optional format and quality settings
|
|
328
|
-
* @returns Promise resolving to the path of the downloaded file
|
|
329
|
-
* @throws {YoutubeException} If download fails
|
|
330
|
-
*
|
|
331
|
-
* @example Download with Default Settings
|
|
332
|
-
* ```typescript
|
|
333
|
-
* const youtube = new Youtube();
|
|
334
|
-
* const filePath = await youtube.download("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
335
|
-
* console.log("Downloaded to:", filePath);
|
|
336
|
-
* ```
|
|
337
|
-
*
|
|
338
|
-
* @example Download with Specific Quality
|
|
339
|
-
* ```typescript
|
|
340
|
-
* const youtube = new Youtube();
|
|
341
|
-
*
|
|
342
|
-
* // Download 1080p video
|
|
343
|
-
* const videoPath = await youtube.download(url, {
|
|
344
|
-
* format: { video: "1080p" },
|
|
345
|
-
* });
|
|
346
|
-
*
|
|
347
|
-
* // Download 720p video with audio
|
|
348
|
-
* const hdPath = await youtube.download(url, {
|
|
349
|
-
* format: { videoandaudio: "720p" },
|
|
350
|
-
* });
|
|
351
|
-
* ```
|
|
352
|
-
*
|
|
353
|
-
* @example Download Audio Only
|
|
354
|
-
* ```typescript
|
|
355
|
-
* const youtube = new Youtube();
|
|
356
|
-
* const audioPath = await youtube.download(url, {
|
|
357
|
-
* format: { audio: "highest" },
|
|
358
|
-
* });
|
|
359
|
-
* ```
|
|
360
|
-
*/
|
|
361
|
-
download(url: string, destination: string): Promise<string>;
|
|
362
|
-
/**
|
|
363
|
-
* Downloads only the audio from a YouTube video.
|
|
364
|
-
* Convenience method that wraps download with audio-only format settings.
|
|
365
|
-
*
|
|
366
|
-
* @param url - The YouTube video URL
|
|
367
|
-
* @param quality - Audio quality preference (defaults to "highest")
|
|
368
|
-
* @returns Promise resolving to the path of the downloaded audio file
|
|
369
|
-
* @throws {YoutubeException} If download fails
|
|
370
|
-
*
|
|
371
|
-
* @example Basic Usage
|
|
372
|
-
* ```typescript
|
|
373
|
-
* const youtube = new Youtube();
|
|
374
|
-
* const audioPath = await youtube.downloadAudio("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
375
|
-
* console.log("Audio downloaded to:", audioPath);
|
|
376
|
-
* ```
|
|
377
|
-
*
|
|
378
|
-
* @example With Quality Option
|
|
379
|
-
* ```typescript
|
|
380
|
-
* const youtube = new Youtube();
|
|
381
|
-
*
|
|
382
|
-
* // Download highest quality audio
|
|
383
|
-
* const hqPath = await youtube.downloadAudio(url, "highest");
|
|
384
|
-
*
|
|
385
|
-
* // Download lowest quality (smaller file)
|
|
386
|
-
* const lqPath = await youtube.downloadAudio(url, "lowest");
|
|
387
|
-
* ```
|
|
388
|
-
*/
|
|
389
|
-
downloadAudio(url: string, destination: string): Promise<string>;
|
|
390
|
-
/**
|
|
391
|
-
* Downloads a video and returns it as a File object.
|
|
392
|
-
* Useful for in-memory processing or streaming without saving to disk.
|
|
393
|
-
*
|
|
394
|
-
* @typeParam F - The format keyword type (video, audio, or videoandaudio)
|
|
395
|
-
* @param url - The YouTube video URL
|
|
396
|
-
* @param options - Optional filename and format settings
|
|
397
|
-
* @returns Promise resolving to a File object containing the video data
|
|
398
|
-
* @throws {YoutubeException} If download fails
|
|
399
|
-
*
|
|
400
|
-
* @example Basic Usage
|
|
401
|
-
* ```typescript
|
|
402
|
-
* const youtube = new Youtube();
|
|
403
|
-
* const file = await youtube.getFile("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
|
404
|
-
*
|
|
405
|
-
* console.log("File name:", file.name);
|
|
406
|
-
* console.log("File size:", file.size, "bytes");
|
|
407
|
-
* console.log("MIME type:", file.type);
|
|
408
|
-
* ```
|
|
409
|
-
*
|
|
410
|
-
* @example With Custom Filename
|
|
411
|
-
* ```typescript
|
|
412
|
-
* const youtube = new Youtube();
|
|
413
|
-
* const file = await youtube.getFile(url, {
|
|
414
|
-
* filename: "my-video.mp4",
|
|
415
|
-
* });
|
|
416
|
-
* ```
|
|
417
|
-
*
|
|
418
|
-
* @example With Format Options
|
|
419
|
-
* ```typescript
|
|
420
|
-
* const youtube = new Youtube();
|
|
421
|
-
* const audioFile = await youtube.getFile(url, {
|
|
422
|
-
* filename: "audio.mp3",
|
|
423
|
-
* format: { audio: "highest" },
|
|
424
|
-
* });
|
|
425
|
-
* ```
|
|
426
|
-
*/
|
|
427
|
-
getFile<F extends YoutubeFormatKeyWordType>(url: string, options?: {
|
|
428
|
-
filename?: string;
|
|
429
|
-
format?: YoutubeFormatOptionsType<F>["format"] | undefined;
|
|
430
|
-
}): Promise<File>;
|
|
431
16
|
getWatchId(url: string): string | null;
|
|
432
17
|
getEmbedUrl(urlOrId: string): string | null;
|
|
433
18
|
getWatchUrl(urlOrId: string): string | null;
|
|
@@ -436,4 +21,4 @@ import { Exception } from "@ooneex/exception";
|
|
|
436
21
|
declare class YoutubeException extends Exception {
|
|
437
22
|
constructor(message: string, data?: Record<string, unknown>);
|
|
438
23
|
}
|
|
439
|
-
export { YoutubeVideoQualityType, YoutubeVideoProgressType,
|
|
24
|
+
export { YoutubeVideoQualityType, YoutubeVideoProgressType, YoutubeVideoFormatType, YoutubeQualityOptionsType, YoutubeFormatOptionsType, YoutubeFormatKeyWordType, YoutubeException, YoutubeAudioQualityType, YoutubeArgsOptionsType, Youtube, IYoutube };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
2
|
+
class u{getWatchId(t){let e=[/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/|youtube\.com\/watch\?.*&v=)([^&\n?#]+)/,/youtube\.com\/shorts\/([^&\n?#]+)/];for(let r of e){let o=t.match(r);if(o?.[1])return o[1]}return null}getEmbedUrl(t){let e=this.getWatchId(t)??t;if(!/^[\w-]{10,12}$/.test(e))return null;return`https://www.youtube.com/embed/${e}`}getWatchUrl(t){let e=this.getWatchId(t)??t;if(!/^[\w-]{10,12}$/.test(e))return null;return`https://www.youtube.com/watch?v=${e}`}}import{Exception as p}from"@ooneex/exception";import{HttpStatus as s}from"@ooneex/http-status";class n extends p{constructor(t,e={}){super(t,{status:s.Code.InternalServerError,data:e});this.name="YoutubeException"}}export{n as YoutubeException,u as Youtube};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=E2B22519AFE2B76E64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["src/Youtube.ts", "src/YoutubeException.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { YtDlp } from \"ytdlp-nodejs\";\nimport type {\n IYoutube,\n YoutubeFormatKeyWordType,\n YoutubeFormatOptionsType,\n YoutubeOptionsType,\n YoutubePlaylistInfoType,\n YoutubeVideoInfoType,\n} from \"./types\";\nimport { YoutubeException } from \"./YoutubeException\";\n\n/**\n * YouTube client for downloading and extracting information from YouTube videos and playlists.\n * Wraps yt-dlp functionality with a clean async API and proper error handling.\n *\n * @example Basic Usage\n * ```typescript\n * import { Youtube } from \"@ooneex/youtube\";\n *\n * const youtube = new Youtube();\n *\n * // Get video information\n * const info = await youtube.getVideoInfo(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n * console.log(info.title, info.duration);\n *\n * // Download a video\n * const filePath = await youtube.download(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n * console.log(`Downloaded to: ${filePath}`);\n * ```\n *\n * @example Download with Quality Options\n * ```typescript\n * const youtube = new Youtube();\n *\n * // Download video in 1080p\n * const path = await youtube.download(url, {\n * format: { video: \"1080p\" },\n * });\n *\n * // Download audio only\n * const audioPath = await youtube.download(url, {\n * format: { audio: \"highest\" },\n * });\n * ```\n */\nexport class Youtube implements IYoutube {\n private readonly ytdlp: YtDlp;\n\n /**\n * Creates a new YouTube client instance.\n *\n * @param options - Optional configuration for binary paths\n * @throws {YoutubeException} If required binary paths are not configured\n *\n * @example\n * ```typescript\n * const youtube = new Youtube();\n * ```\n *\n * @example With Custom Paths\n * ```typescript\n * const youtube = new Youtube({\n * binaryPath: \"/custom/path/to/yt-dlp\",\n * ffmpegPath: \"/custom/path/to/ffmpeg\",\n * });\n * ```\n */\n constructor(options: YoutubeOptionsType = {}) {\n const binaryPath = options.binaryPath || Bun.env.YOUTUBE_YTDLP_PATH;\n const ffmpegPath = options.ffmpegPath || Bun.env.YOUTUBE_FFMPEG_PATH;\n\n if (!binaryPath) {\n throw new YoutubeException(\n \"yt-dlp binary path is required. Please provide it through the constructor options or set the YOUTUBE_YTDLP_PATH environment variable.\",\n );\n }\n\n if (!ffmpegPath) {\n throw new YoutubeException(\n \"ffmpeg binary path is required. Please provide it through the constructor options or set the YOUTUBE_FFMPEG_PATH environment variable.\",\n );\n }\n\n this.ytdlp = new YtDlp({\n binaryPath,\n ffmpegPath,\n });\n }\n\n /**\n * Retrieves detailed metadata for a YouTube video.\n *\n * @param url - The YouTube video URL\n * @returns Promise resolving to video information including title, description,\n * duration, view count, available formats, and more\n * @throws {YoutubeException} If the video cannot be accessed or URL is invalid\n *\n * @example\n * ```typescript\n * const youtube = new Youtube();\n * const info = await youtube.getVideoInfo(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n *\n * console.log(\"Title:\", info.title);\n * console.log(\"Duration:\", info.duration, \"seconds\");\n * console.log(\"Views:\", info.view_count);\n * console.log(\"Description:\", info.description);\n * console.log(\"Available formats:\", info.formats.length);\n * ```\n */\n public async getVideoInfo(url: string): Promise<YoutubeVideoInfoType> {\n try {\n return await this.ytdlp.getInfoAsync<\"video\">(url);\n } catch (error) {\n throw new YoutubeException(`Failed to get video info: ${(error as Error).message}`, {\n data: { url },\n });\n }\n }\n\n /**\n * Retrieves information about a YouTube playlist including all videos.\n *\n * @param url - The YouTube playlist URL\n * @returns Promise resolving to playlist metadata and video entries\n * @throws {YoutubeException} If the playlist cannot be accessed or URL is invalid\n *\n * @example\n * ```typescript\n * const youtube = new Youtube();\n * const playlist = await youtube.getPlaylistInfo(\n * \"https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf\"\n * );\n *\n * console.log(\"Playlist:\", playlist.title);\n * console.log(\"Video count:\", playlist.entries.length);\n *\n * // Iterate over videos in the playlist\n * for (const video of playlist.entries) {\n * console.log(`- ${video.title} (${video.duration}s)`);\n * }\n * ```\n */\n public async getPlaylistInfo(url: string): Promise<YoutubePlaylistInfoType> {\n try {\n return await this.ytdlp.getInfoAsync<\"playlist\">(url);\n } catch (error) {\n throw new YoutubeException(`Failed to get playlist info: ${(error as Error).message}`, {\n data: { url },\n });\n }\n }\n\n /**\n * Downloads a video to the local filesystem.\n *\n * @typeParam F - The format keyword type (video, audio, or videoandaudio)\n * @param url - The YouTube video URL\n * @param options - Optional format and quality settings\n * @returns Promise resolving to the path of the downloaded file\n * @throws {YoutubeException} If download fails\n *\n * @example Download with Default Settings\n * ```typescript\n * const youtube = new Youtube();\n * const filePath = await youtube.download(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n * console.log(\"Downloaded to:\", filePath);\n * ```\n *\n * @example Download with Specific Quality\n * ```typescript\n * const youtube = new Youtube();\n *\n * // Download 1080p video\n * const videoPath = await youtube.download(url, {\n * format: { video: \"1080p\" },\n * });\n *\n * // Download 720p video with audio\n * const hdPath = await youtube.download(url, {\n * format: { videoandaudio: \"720p\" },\n * });\n * ```\n *\n * @example Download Audio Only\n * ```typescript\n * const youtube = new Youtube();\n * const audioPath = await youtube.download(url, {\n * format: { audio: \"highest\" },\n * });\n * ```\n */\n public async download(url: string, destination: string): Promise<string> {\n try {\n return await this.ytdlp.downloadAsync(this.getWatchId(url) || \"\", {\n format: { filter: \"audioandvideo\", type: \"mp4\" },\n output: destination,\n });\n } catch (error) {\n throw new YoutubeException(`Failed to download video: ${(error as Error).message}`, {\n data: { url },\n });\n }\n }\n\n /**\n * Downloads only the audio from a YouTube video.\n * Convenience method that wraps download with audio-only format settings.\n *\n * @param url - The YouTube video URL\n * @param quality - Audio quality preference (defaults to \"highest\")\n * @returns Promise resolving to the path of the downloaded audio file\n * @throws {YoutubeException} If download fails\n *\n * @example Basic Usage\n * ```typescript\n * const youtube = new Youtube();\n * const audioPath = await youtube.downloadAudio(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n * console.log(\"Audio downloaded to:\", audioPath);\n * ```\n *\n * @example With Quality Option\n * ```typescript\n * const youtube = new Youtube();\n *\n * // Download highest quality audio\n * const hqPath = await youtube.downloadAudio(url, \"highest\");\n *\n * // Download lowest quality (smaller file)\n * const lqPath = await youtube.downloadAudio(url, \"lowest\");\n * ```\n */\n public async downloadAudio(url: string, destination: string): Promise<string> {\n try {\n return await this.ytdlp.downloadAsync(this.getWatchId(url) || \"\", {\n format: { filter: \"audioonly\", type: \"mp3\" },\n output: destination,\n });\n } catch (error) {\n throw new YoutubeException(`Failed to download audio: ${(error as Error).message}`, {\n data: { url },\n });\n }\n }\n\n /**\n * Downloads a video and returns it as a File object.\n * Useful for in-memory processing or streaming without saving to disk.\n *\n * @typeParam F - The format keyword type (video, audio, or videoandaudio)\n * @param url - The YouTube video URL\n * @param options - Optional filename and format settings\n * @returns Promise resolving to a File object containing the video data\n * @throws {YoutubeException} If download fails\n *\n * @example Basic Usage\n * ```typescript\n * const youtube = new Youtube();\n * const file = await youtube.getFile(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\");\n *\n * console.log(\"File name:\", file.name);\n * console.log(\"File size:\", file.size, \"bytes\");\n * console.log(\"MIME type:\", file.type);\n * ```\n *\n * @example With Custom Filename\n * ```typescript\n * const youtube = new Youtube();\n * const file = await youtube.getFile(url, {\n * filename: \"my-video.mp4\",\n * });\n * ```\n *\n * @example With Format Options\n * ```typescript\n * const youtube = new Youtube();\n * const audioFile = await youtube.getFile(url, {\n * filename: \"audio.mp3\",\n * format: { audio: \"highest\" },\n * });\n * ```\n */\n public async getFile<F extends YoutubeFormatKeyWordType>(\n url: string,\n options?: { filename?: string; format?: YoutubeFormatOptionsType<F>[\"format\"] | undefined },\n ): Promise<File> {\n try {\n const fileOptions = options ? { filename: options.filename, format: options.format } : undefined;\n return await this.ytdlp.getFileAsync(\n this.getWatchId(url) || \"\",\n fileOptions as Parameters<typeof this.ytdlp.getFileAsync<F>>[1],\n );\n } catch (error) {\n throw new YoutubeException(`Failed to get file: ${(error as Error).message}`, {\n data: { url },\n });\n }\n }\n\n public getWatchId(url: string): string | null {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/v\\/|youtube\\.com\\/watch\\?.*&v=)([^&\\n?#]+)/,\n /youtube\\.com\\/shorts\\/([^&\\n?#]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match?.[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n public getEmbedUrl(urlOrId: string): string | null {\n const videoId = this.getWatchId(urlOrId) ?? urlOrId;\n\n // Validate that it looks like a YouTube video ID (typically 11 characters, alphanumeric with - and _)\n if (!/^[\\w-]{10,12}$/.test(videoId)) {\n return null;\n }\n\n return `https://www.youtube.com/embed/${videoId}`;\n }\n\n public getWatchUrl(urlOrId: string): string | null {\n const videoId = this.getWatchId(urlOrId) ?? urlOrId;\n\n // Validate that it looks like a YouTube video ID (typically 11 characters, alphanumeric with - and _)\n if (!/^[\\w-]{10,12}$/.test(videoId)) {\n return null;\n }\n\n return `https://www.youtube.com/watch?v=${videoId}`;\n }\n}\n",
|
|
5
|
+
"import type { IYoutube } from \"./types\";\n\nexport class Youtube implements IYoutube {\n public getWatchId(url: string): string | null {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/v\\/|youtube\\.com\\/watch\\?.*&v=)([^&\\n?#]+)/,\n /youtube\\.com\\/shorts\\/([^&\\n?#]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match?.[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n public getEmbedUrl(urlOrId: string): string | null {\n const videoId = this.getWatchId(urlOrId) ?? urlOrId;\n\n if (!/^[\\w-]{10,12}$/.test(videoId)) {\n return null;\n }\n\n return `https://www.youtube.com/embed/${videoId}`;\n }\n\n public getWatchUrl(urlOrId: string): string | null {\n const videoId = this.getWatchId(urlOrId) ?? urlOrId;\n\n if (!/^[\\w-]{10,12}$/.test(videoId)) {\n return null;\n }\n\n return `https://www.youtube.com/watch?v=${videoId}`;\n }\n}\n",
|
|
6
6
|
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class YoutubeException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"YoutubeException\";\n }\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": ";
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": ";AAEO,MAAM,CAA4B,CAChC,UAAU,CAAC,EAA4B,CAC5C,IAAM,EAAW,CACf,wHACA,mCACF,EAEA,QAAW,KAAW,EAAU,CAC9B,IAAM,EAAQ,EAAI,MAAM,CAAO,EAC/B,GAAI,IAAQ,GACV,OAAO,EAAM,GAIjB,OAAO,KAGF,WAAW,CAAC,EAAgC,CACjD,IAAM,EAAU,KAAK,WAAW,CAAO,GAAK,EAE5C,GAAI,CAAC,iBAAiB,KAAK,CAAO,EAChC,OAAO,KAGT,MAAO,iCAAiC,IAGnC,WAAW,CAAC,EAAgC,CACjD,IAAM,EAAU,KAAK,WAAW,CAAO,GAAK,EAE5C,GAAI,CAAC,iBAAiB,KAAK,CAAO,EAChC,OAAO,KAGT,MAAO,mCAAmC,IAE9C,CCtCA,oBAAS,0BACT,qBAAS,4BAEF,MAAM,UAAyB,CAAU,CAC9C,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,oBACxB,MACF,CAAC,EACD,KAAK,KAAO,mBAEhB",
|
|
9
|
+
"debugId": "E2B22519AFE2B76E64756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/youtube",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.0
|
|
3
|
+
"description": "YouTube video downloader and metadata extraction library for fetching video information, thumbnails, and media streams",
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"npm:publish": "bun publish --tolerate-republish --access public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@ooneex/exception": "0.0.
|
|
32
|
-
"@ooneex/http-status": "0.0.
|
|
31
|
+
"@ooneex/exception": "0.0.18",
|
|
32
|
+
"@ooneex/http-status": "0.0.18",
|
|
33
33
|
"ytdlp-nodejs": "^2.3.5"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|