@blagoja/ts-dlp 0.1.0 → 0.1.2
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 +10 -15
- package/dist/index.cjs +170 -0
- package/dist/index.d.cts +109 -0
- package/dist/index.d.ts +109 -3
- package/dist/index.js +142 -4
- package/package.json +12 -6
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ pip install -U yt-dlp
|
|
|
57
57
|
|
|
58
58
|
Official project:
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
https://www.npmjs.com/package/@blagoja/ts-dlp
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
@@ -108,24 +108,19 @@ await ytdlp
|
|
|
108
108
|
## v0.1.0 - Foundation
|
|
109
109
|
|
|
110
110
|
- [x] Detect yt-dlp installation
|
|
111
|
-
- [
|
|
111
|
+
- [x] Execute simple yt-dlp commands
|
|
112
112
|
- [ ] Basic command runner
|
|
113
113
|
- [ ] Error handling
|
|
114
114
|
- [ ] Capture stdout/stderr
|
|
115
115
|
- [ ] TypeScript support
|
|
116
116
|
- [ ] Unit test setup
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
## v0.2.0 - Download API
|
|
121
|
-
|
|
122
|
-
- [ ] `.download(url)`
|
|
123
|
-
- [ ] `.run()`
|
|
124
|
-
- [ ] `.output(path)`
|
|
117
|
+
- [x] `.download(url)`
|
|
118
|
+
- [x] `.run()`
|
|
119
|
+
- [x] `.output(path)`
|
|
125
120
|
- [ ] `.format(format)`
|
|
126
|
-
- [
|
|
121
|
+
- [x] `.audio()`
|
|
127
122
|
- [ ] `.video()`
|
|
128
|
-
- [
|
|
123
|
+
- [x] `.resolution()`
|
|
129
124
|
- [ ] `.fps()`
|
|
130
125
|
|
|
131
126
|
Example:
|
|
@@ -136,7 +131,7 @@ await ytdlp.download(url).resolution("720p").run();
|
|
|
136
131
|
|
|
137
132
|
---
|
|
138
133
|
|
|
139
|
-
## v0.
|
|
134
|
+
## v0.2.0 - Metadata & Information
|
|
140
135
|
|
|
141
136
|
- [ ] `.info()`
|
|
142
137
|
- [ ] Video metadata parsing
|
|
@@ -152,7 +147,7 @@ const info = await ytdlp.info(url);
|
|
|
152
147
|
|
|
153
148
|
---
|
|
154
149
|
|
|
155
|
-
## v0.
|
|
150
|
+
## v0.3.0 - Advanced Features
|
|
156
151
|
|
|
157
152
|
- [ ] Subtitle support
|
|
158
153
|
- [ ] Thumbnail downloads
|
|
@@ -163,7 +158,7 @@ const info = await ytdlp.info(url);
|
|
|
163
158
|
|
|
164
159
|
---
|
|
165
160
|
|
|
166
|
-
## v0.
|
|
161
|
+
## v0.4.0 - Developer Experience
|
|
167
162
|
|
|
168
163
|
- [ ] Better typed builders
|
|
169
164
|
- [ ] Presets
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
download: () => download
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/internal/runner.ts
|
|
28
|
+
var import_execa = require("execa");
|
|
29
|
+
async function runYtDlp(args) {
|
|
30
|
+
await (0, import_execa.execa)("yt-dlp", ["--js-runtimes", "node", ...args], {
|
|
31
|
+
stdio: "inherit"
|
|
32
|
+
}).catch(handleEnoent);
|
|
33
|
+
}
|
|
34
|
+
function handleEnoent(error) {
|
|
35
|
+
if (error instanceof import_execa.ExecaError && error.code === "ENOENT") {
|
|
36
|
+
throw new Error(
|
|
37
|
+
"yt-dlp is not installed or not in PATH. Please refer to https://github.com/yt-dlp/yt-dlp#installation"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/download.ts
|
|
44
|
+
var DownloadBuilder = class {
|
|
45
|
+
constructor(url) {
|
|
46
|
+
this.url = url;
|
|
47
|
+
}
|
|
48
|
+
url;
|
|
49
|
+
args = [];
|
|
50
|
+
videoFormat;
|
|
51
|
+
audioFormat;
|
|
52
|
+
outputDir;
|
|
53
|
+
filenameTemplate;
|
|
54
|
+
/**
|
|
55
|
+
* Set the desired resolution for the video download.
|
|
56
|
+
* The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
57
|
+
* For example, if you specify "720p", it will select the best available video format that is 720p or lower.
|
|
58
|
+
*
|
|
59
|
+
* @param res The desired resolution for the video. You can specify common resolutions like "720p", "1080p", etc. The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
60
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
61
|
+
*/
|
|
62
|
+
resolution(res) {
|
|
63
|
+
const height = res.replace("p", "");
|
|
64
|
+
this.videoFormat = `bestvideo[height<=${height}]`;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Set the output directory for the downloaded file. You can specify a directory path like "downloads".
|
|
69
|
+
* If not specified, the file will be saved in the current working directory.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
73
|
+
* .output("downloads")
|
|
74
|
+
* .run();
|
|
75
|
+
*
|
|
76
|
+
* @param dir The output directory where the downloaded file will be saved.
|
|
77
|
+
* You can specify a directory path like "downloads". If not specified, the file will be saved in the current working directory.
|
|
78
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
79
|
+
*/
|
|
80
|
+
output(dir) {
|
|
81
|
+
this.outputDir = dir;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Set the desired audio codec for the download.
|
|
86
|
+
* The method will select the best available audio format that matches the specified codec.
|
|
87
|
+
* If no codec is specified, it will select the best available audio format regardless of codec.
|
|
88
|
+
*
|
|
89
|
+
* @example // Specifying an audio codec
|
|
90
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
91
|
+
* .audio("mp3")
|
|
92
|
+
* .run();
|
|
93
|
+
*
|
|
94
|
+
* @param codec The desired audio codec for the download. You can specify common audio codecs like "mp3", "aac", "opus", etc. If no codec is specified, it will select the best available audio format.
|
|
95
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
96
|
+
*/
|
|
97
|
+
audio(codec) {
|
|
98
|
+
this.audioFormat = codec ? `bestaudio[ext=${codec}]` : "bestaudio";
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Set the filename template for the downloaded file.
|
|
103
|
+
* The callback receives common output fields as named parameters which are
|
|
104
|
+
* automatically mapped to their values at download time.
|
|
105
|
+
*
|
|
106
|
+
* @example // Using a string template
|
|
107
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
108
|
+
* .output("downloads")
|
|
109
|
+
* .filename("%(title)s.%(ext)s")
|
|
110
|
+
*
|
|
111
|
+
* @example // Using a callback to specify a custom filename template
|
|
112
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
113
|
+
* .output("downloads")
|
|
114
|
+
* .filename(({ title, ext }) => `${title}.${ext}`)
|
|
115
|
+
* .run();
|
|
116
|
+
*
|
|
117
|
+
* @param template A callback that receives output fields and returns a filename string. If omitted, defaults to the video title with its original extension.
|
|
118
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
119
|
+
*/
|
|
120
|
+
filename(template) {
|
|
121
|
+
if (typeof template === "string") {
|
|
122
|
+
this.filenameTemplate = template;
|
|
123
|
+
} else {
|
|
124
|
+
const fields = new Proxy({}, {
|
|
125
|
+
get(_, prop) {
|
|
126
|
+
return `%(${prop})s`;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
this.filenameTemplate = template(fields);
|
|
130
|
+
}
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Execute the download with the specified options.
|
|
135
|
+
* This will run yt-dlp with the accumulated arguments and the provided URL.
|
|
136
|
+
* The output will be displayed in the console.
|
|
137
|
+
*
|
|
138
|
+
* @throws Will throw an error if yt-dlp is not installed or not in PATH, or if any other error occurs during the execution of yt-dlp.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
142
|
+
* .resolution("720p")
|
|
143
|
+
* .output("downloads/%(title)s.%(ext)s")
|
|
144
|
+
* .run();
|
|
145
|
+
*
|
|
146
|
+
*/
|
|
147
|
+
async run() {
|
|
148
|
+
const args = [...this.args];
|
|
149
|
+
if (this.videoFormat || this.audioFormat) {
|
|
150
|
+
const video = this.videoFormat ?? "bestvideo";
|
|
151
|
+
const audio = this.audioFormat ?? "bestaudio";
|
|
152
|
+
args.push("-f", `${video}+${audio}/best`);
|
|
153
|
+
}
|
|
154
|
+
if (this.outputDir || this.filenameTemplate) {
|
|
155
|
+
const dir = this.outputDir ?? "";
|
|
156
|
+
const file = this.filenameTemplate ?? "%(title)s.%(ext)s";
|
|
157
|
+
args.push("-o", dir ? `${dir}/${file}` : file);
|
|
158
|
+
}
|
|
159
|
+
await runYtDlp([...args, this.url]);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// src/index.ts
|
|
164
|
+
function download(url) {
|
|
165
|
+
return new DownloadBuilder(url);
|
|
166
|
+
}
|
|
167
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
168
|
+
0 && (module.exports = {
|
|
169
|
+
download
|
|
170
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
type Resolution = "144p" | "240p" | "360p" | "480p" | "720p" | "1080p" | "1440p" | "2160p" | (string & {});
|
|
2
|
+
type OutputFields = {
|
|
3
|
+
title: string;
|
|
4
|
+
ext: string;
|
|
5
|
+
id: string;
|
|
6
|
+
uploader: string;
|
|
7
|
+
uploader_id: string;
|
|
8
|
+
channel: string;
|
|
9
|
+
upload_date: string;
|
|
10
|
+
release_date: string;
|
|
11
|
+
epoch: string;
|
|
12
|
+
height: string;
|
|
13
|
+
width: string;
|
|
14
|
+
resolution: string;
|
|
15
|
+
fps: string;
|
|
16
|
+
vcodec: string;
|
|
17
|
+
acodec: string;
|
|
18
|
+
duration_string: string;
|
|
19
|
+
playlist_title: string;
|
|
20
|
+
playlist_index: string;
|
|
21
|
+
autonumber: string;
|
|
22
|
+
};
|
|
23
|
+
type AudioCodec = "opus" | "aac" | "m4a" | "mp3" | "flac" | "wav" | (string & {});
|
|
24
|
+
|
|
25
|
+
declare class DownloadBuilder {
|
|
26
|
+
private readonly url;
|
|
27
|
+
private readonly args;
|
|
28
|
+
private videoFormat?;
|
|
29
|
+
private audioFormat?;
|
|
30
|
+
private outputDir?;
|
|
31
|
+
private filenameTemplate?;
|
|
32
|
+
constructor(url: string);
|
|
33
|
+
/**
|
|
34
|
+
* Set the desired resolution for the video download.
|
|
35
|
+
* The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
36
|
+
* For example, if you specify "720p", it will select the best available video format that is 720p or lower.
|
|
37
|
+
*
|
|
38
|
+
* @param res The desired resolution for the video. You can specify common resolutions like "720p", "1080p", etc. The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
39
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
40
|
+
*/
|
|
41
|
+
resolution(res: Resolution): this;
|
|
42
|
+
/**
|
|
43
|
+
* Set the output directory for the downloaded file. You can specify a directory path like "downloads".
|
|
44
|
+
* If not specified, the file will be saved in the current working directory.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
48
|
+
* .output("downloads")
|
|
49
|
+
* .run();
|
|
50
|
+
*
|
|
51
|
+
* @param dir The output directory where the downloaded file will be saved.
|
|
52
|
+
* You can specify a directory path like "downloads". If not specified, the file will be saved in the current working directory.
|
|
53
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
54
|
+
*/
|
|
55
|
+
output(dir: string): this;
|
|
56
|
+
/**
|
|
57
|
+
* Set the desired audio codec for the download.
|
|
58
|
+
* The method will select the best available audio format that matches the specified codec.
|
|
59
|
+
* If no codec is specified, it will select the best available audio format regardless of codec.
|
|
60
|
+
*
|
|
61
|
+
* @example // Specifying an audio codec
|
|
62
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
63
|
+
* .audio("mp3")
|
|
64
|
+
* .run();
|
|
65
|
+
*
|
|
66
|
+
* @param codec The desired audio codec for the download. You can specify common audio codecs like "mp3", "aac", "opus", etc. If no codec is specified, it will select the best available audio format.
|
|
67
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
68
|
+
*/
|
|
69
|
+
audio(codec?: AudioCodec): this;
|
|
70
|
+
/**
|
|
71
|
+
* Set the filename template for the downloaded file.
|
|
72
|
+
* The callback receives common output fields as named parameters which are
|
|
73
|
+
* automatically mapped to their values at download time.
|
|
74
|
+
*
|
|
75
|
+
* @example // Using a string template
|
|
76
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
77
|
+
* .output("downloads")
|
|
78
|
+
* .filename("%(title)s.%(ext)s")
|
|
79
|
+
*
|
|
80
|
+
* @example // Using a callback to specify a custom filename template
|
|
81
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
82
|
+
* .output("downloads")
|
|
83
|
+
* .filename(({ title, ext }) => `${title}.${ext}`)
|
|
84
|
+
* .run();
|
|
85
|
+
*
|
|
86
|
+
* @param template A callback that receives output fields and returns a filename string. If omitted, defaults to the video title with its original extension.
|
|
87
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
88
|
+
*/
|
|
89
|
+
filename(template: ((fields: OutputFields) => string) | string): this;
|
|
90
|
+
/**
|
|
91
|
+
* Execute the download with the specified options.
|
|
92
|
+
* This will run yt-dlp with the accumulated arguments and the provided URL.
|
|
93
|
+
* The output will be displayed in the console.
|
|
94
|
+
*
|
|
95
|
+
* @throws Will throw an error if yt-dlp is not installed or not in PATH, or if any other error occurs during the execution of yt-dlp.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
99
|
+
* .resolution("720p")
|
|
100
|
+
* .output("downloads/%(title)s.%(ext)s")
|
|
101
|
+
* .run();
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
run(): Promise<void>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare function download(url: string): DownloadBuilder;
|
|
108
|
+
|
|
109
|
+
export { download };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
type Resolution = "144p" | "240p" | "360p" | "480p" | "720p" | "1080p" | "1440p" | "2160p" | (string & {});
|
|
2
|
+
type OutputFields = {
|
|
3
|
+
title: string;
|
|
4
|
+
ext: string;
|
|
5
|
+
id: string;
|
|
6
|
+
uploader: string;
|
|
7
|
+
uploader_id: string;
|
|
8
|
+
channel: string;
|
|
9
|
+
upload_date: string;
|
|
10
|
+
release_date: string;
|
|
11
|
+
epoch: string;
|
|
12
|
+
height: string;
|
|
13
|
+
width: string;
|
|
14
|
+
resolution: string;
|
|
15
|
+
fps: string;
|
|
16
|
+
vcodec: string;
|
|
17
|
+
acodec: string;
|
|
18
|
+
duration_string: string;
|
|
19
|
+
playlist_title: string;
|
|
20
|
+
playlist_index: string;
|
|
21
|
+
autonumber: string;
|
|
22
|
+
};
|
|
23
|
+
type AudioCodec = "opus" | "aac" | "m4a" | "mp3" | "flac" | "wav" | (string & {});
|
|
24
|
+
|
|
25
|
+
declare class DownloadBuilder {
|
|
26
|
+
private readonly url;
|
|
27
|
+
private readonly args;
|
|
28
|
+
private videoFormat?;
|
|
29
|
+
private audioFormat?;
|
|
30
|
+
private outputDir?;
|
|
31
|
+
private filenameTemplate?;
|
|
32
|
+
constructor(url: string);
|
|
33
|
+
/**
|
|
34
|
+
* Set the desired resolution for the video download.
|
|
35
|
+
* The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
36
|
+
* For example, if you specify "720p", it will select the best available video format that is 720p or lower.
|
|
37
|
+
*
|
|
38
|
+
* @param res The desired resolution for the video. You can specify common resolutions like "720p", "1080p", etc. The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
39
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
40
|
+
*/
|
|
41
|
+
resolution(res: Resolution): this;
|
|
42
|
+
/**
|
|
43
|
+
* Set the output directory for the downloaded file. You can specify a directory path like "downloads".
|
|
44
|
+
* If not specified, the file will be saved in the current working directory.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
48
|
+
* .output("downloads")
|
|
49
|
+
* .run();
|
|
50
|
+
*
|
|
51
|
+
* @param dir The output directory where the downloaded file will be saved.
|
|
52
|
+
* You can specify a directory path like "downloads". If not specified, the file will be saved in the current working directory.
|
|
53
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
54
|
+
*/
|
|
55
|
+
output(dir: string): this;
|
|
56
|
+
/**
|
|
57
|
+
* Set the desired audio codec for the download.
|
|
58
|
+
* The method will select the best available audio format that matches the specified codec.
|
|
59
|
+
* If no codec is specified, it will select the best available audio format regardless of codec.
|
|
60
|
+
*
|
|
61
|
+
* @example // Specifying an audio codec
|
|
62
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
63
|
+
* .audio("mp3")
|
|
64
|
+
* .run();
|
|
65
|
+
*
|
|
66
|
+
* @param codec The desired audio codec for the download. You can specify common audio codecs like "mp3", "aac", "opus", etc. If no codec is specified, it will select the best available audio format.
|
|
67
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
68
|
+
*/
|
|
69
|
+
audio(codec?: AudioCodec): this;
|
|
70
|
+
/**
|
|
71
|
+
* Set the filename template for the downloaded file.
|
|
72
|
+
* The callback receives common output fields as named parameters which are
|
|
73
|
+
* automatically mapped to their values at download time.
|
|
74
|
+
*
|
|
75
|
+
* @example // Using a string template
|
|
76
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
77
|
+
* .output("downloads")
|
|
78
|
+
* .filename("%(title)s.%(ext)s")
|
|
79
|
+
*
|
|
80
|
+
* @example // Using a callback to specify a custom filename template
|
|
81
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
82
|
+
* .output("downloads")
|
|
83
|
+
* .filename(({ title, ext }) => `${title}.${ext}`)
|
|
84
|
+
* .run();
|
|
85
|
+
*
|
|
86
|
+
* @param template A callback that receives output fields and returns a filename string. If omitted, defaults to the video title with its original extension.
|
|
87
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
88
|
+
*/
|
|
89
|
+
filename(template: ((fields: OutputFields) => string) | string): this;
|
|
90
|
+
/**
|
|
91
|
+
* Execute the download with the specified options.
|
|
92
|
+
* This will run yt-dlp with the accumulated arguments and the provided URL.
|
|
93
|
+
* The output will be displayed in the console.
|
|
94
|
+
*
|
|
95
|
+
* @throws Will throw an error if yt-dlp is not installed or not in PATH, or if any other error occurs during the execution of yt-dlp.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
99
|
+
* .resolution("720p")
|
|
100
|
+
* .output("downloads/%(title)s.%(ext)s")
|
|
101
|
+
* .run();
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
run(): Promise<void>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare function download(url: string): DownloadBuilder;
|
|
108
|
+
|
|
109
|
+
export { download };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,143 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/internal/runner.ts
|
|
2
|
+
import { execa, ExecaError } from "execa";
|
|
3
|
+
async function runYtDlp(args) {
|
|
4
|
+
await execa("yt-dlp", ["--js-runtimes", "node", ...args], {
|
|
5
|
+
stdio: "inherit"
|
|
6
|
+
}).catch(handleEnoent);
|
|
4
7
|
}
|
|
5
|
-
|
|
8
|
+
function handleEnoent(error) {
|
|
9
|
+
if (error instanceof ExecaError && error.code === "ENOENT") {
|
|
10
|
+
throw new Error(
|
|
11
|
+
"yt-dlp is not installed or not in PATH. Please refer to https://github.com/yt-dlp/yt-dlp#installation"
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/download.ts
|
|
18
|
+
var DownloadBuilder = class {
|
|
19
|
+
constructor(url) {
|
|
20
|
+
this.url = url;
|
|
21
|
+
}
|
|
22
|
+
url;
|
|
23
|
+
args = [];
|
|
24
|
+
videoFormat;
|
|
25
|
+
audioFormat;
|
|
26
|
+
outputDir;
|
|
27
|
+
filenameTemplate;
|
|
28
|
+
/**
|
|
29
|
+
* Set the desired resolution for the video download.
|
|
30
|
+
* The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
31
|
+
* For example, if you specify "720p", it will select the best available video format that is 720p or lower.
|
|
32
|
+
*
|
|
33
|
+
* @param res The desired resolution for the video. You can specify common resolutions like "720p", "1080p", etc. The method will automatically select the best video format that is less than or equal to the specified resolution.
|
|
34
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
35
|
+
*/
|
|
36
|
+
resolution(res) {
|
|
37
|
+
const height = res.replace("p", "");
|
|
38
|
+
this.videoFormat = `bestvideo[height<=${height}]`;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Set the output directory for the downloaded file. You can specify a directory path like "downloads".
|
|
43
|
+
* If not specified, the file will be saved in the current working directory.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
47
|
+
* .output("downloads")
|
|
48
|
+
* .run();
|
|
49
|
+
*
|
|
50
|
+
* @param dir The output directory where the downloaded file will be saved.
|
|
51
|
+
* You can specify a directory path like "downloads". If not specified, the file will be saved in the current working directory.
|
|
52
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
53
|
+
*/
|
|
54
|
+
output(dir) {
|
|
55
|
+
this.outputDir = dir;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the desired audio codec for the download.
|
|
60
|
+
* The method will select the best available audio format that matches the specified codec.
|
|
61
|
+
* If no codec is specified, it will select the best available audio format regardless of codec.
|
|
62
|
+
*
|
|
63
|
+
* @example // Specifying an audio codec
|
|
64
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
65
|
+
* .audio("mp3")
|
|
66
|
+
* .run();
|
|
67
|
+
*
|
|
68
|
+
* @param codec The desired audio codec for the download. You can specify common audio codecs like "mp3", "aac", "opus", etc. If no codec is specified, it will select the best available audio format.
|
|
69
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
70
|
+
*/
|
|
71
|
+
audio(codec) {
|
|
72
|
+
this.audioFormat = codec ? `bestaudio[ext=${codec}]` : "bestaudio";
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Set the filename template for the downloaded file.
|
|
77
|
+
* The callback receives common output fields as named parameters which are
|
|
78
|
+
* automatically mapped to their values at download time.
|
|
79
|
+
*
|
|
80
|
+
* @example // Using a string template
|
|
81
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
82
|
+
* .output("downloads")
|
|
83
|
+
* .filename("%(title)s.%(ext)s")
|
|
84
|
+
*
|
|
85
|
+
* @example // Using a callback to specify a custom filename template
|
|
86
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
87
|
+
* .output("downloads")
|
|
88
|
+
* .filename(({ title, ext }) => `${title}.${ext}`)
|
|
89
|
+
* .run();
|
|
90
|
+
*
|
|
91
|
+
* @param template A callback that receives output fields and returns a filename string. If omitted, defaults to the video title with its original extension.
|
|
92
|
+
* @returns The current instance of DownloadBuilder for method chaining.
|
|
93
|
+
*/
|
|
94
|
+
filename(template) {
|
|
95
|
+
if (typeof template === "string") {
|
|
96
|
+
this.filenameTemplate = template;
|
|
97
|
+
} else {
|
|
98
|
+
const fields = new Proxy({}, {
|
|
99
|
+
get(_, prop) {
|
|
100
|
+
return `%(${prop})s`;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
this.filenameTemplate = template(fields);
|
|
104
|
+
}
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Execute the download with the specified options.
|
|
109
|
+
* This will run yt-dlp with the accumulated arguments and the provided URL.
|
|
110
|
+
* The output will be displayed in the console.
|
|
111
|
+
*
|
|
112
|
+
* @throws Will throw an error if yt-dlp is not installed or not in PATH, or if any other error occurs during the execution of yt-dlp.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* download("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
116
|
+
* .resolution("720p")
|
|
117
|
+
* .output("downloads/%(title)s.%(ext)s")
|
|
118
|
+
* .run();
|
|
119
|
+
*
|
|
120
|
+
*/
|
|
121
|
+
async run() {
|
|
122
|
+
const args = [...this.args];
|
|
123
|
+
if (this.videoFormat || this.audioFormat) {
|
|
124
|
+
const video = this.videoFormat ?? "bestvideo";
|
|
125
|
+
const audio = this.audioFormat ?? "bestaudio";
|
|
126
|
+
args.push("-f", `${video}+${audio}/best`);
|
|
127
|
+
}
|
|
128
|
+
if (this.outputDir || this.filenameTemplate) {
|
|
129
|
+
const dir = this.outputDir ?? "";
|
|
130
|
+
const file = this.filenameTemplate ?? "%(title)s.%(ext)s";
|
|
131
|
+
args.push("-o", dir ? `${dir}/${file}` : file);
|
|
132
|
+
}
|
|
133
|
+
await runYtDlp([...args, this.url]);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/index.ts
|
|
138
|
+
function download(url) {
|
|
139
|
+
return new DownloadBuilder(url);
|
|
140
|
+
}
|
|
141
|
+
export {
|
|
142
|
+
download
|
|
143
|
+
};
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blagoja/ts-dlp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A human readable TypeScript wrapper for yt-dlp",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
9
|
"import": "./dist/index.js",
|
|
10
|
-
"types": "./dist/index.d.ts"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.cjs"
|
|
11
12
|
}
|
|
12
13
|
},
|
|
13
14
|
"scripts": {
|
|
14
|
-
"build": "
|
|
15
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
15
16
|
"dev": "tsx src/index.ts",
|
|
16
17
|
"lint": "eslint src",
|
|
17
18
|
"prepublishOnly": "npm run build"
|
|
@@ -22,6 +23,10 @@
|
|
|
22
23
|
"downloader",
|
|
23
24
|
"wrapper"
|
|
24
25
|
],
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/blagojablazhevski/ts-dlp.git"
|
|
29
|
+
},
|
|
25
30
|
"author": "Blagoja Blazhevski",
|
|
26
31
|
"files": [
|
|
27
32
|
"dist"
|
|
@@ -29,15 +34,16 @@
|
|
|
29
34
|
"engines": {
|
|
30
35
|
"node": ">=18"
|
|
31
36
|
},
|
|
32
|
-
"license": "
|
|
37
|
+
"license": "MIT",
|
|
33
38
|
"type": "module",
|
|
34
39
|
"devDependencies": {
|
|
35
40
|
"@types/node": "^25.9.1",
|
|
36
|
-
"typescript-eslint": "^8.60.0",
|
|
37
41
|
"eslint": "^10.4.0",
|
|
38
42
|
"jiti": "^2.7.0",
|
|
43
|
+
"tsup": "^8.5.1",
|
|
39
44
|
"tsx": "^4.22.3",
|
|
40
|
-
"typescript": "^6.0.3"
|
|
45
|
+
"typescript": "^6.0.3",
|
|
46
|
+
"typescript-eslint": "^8.60.0"
|
|
41
47
|
},
|
|
42
48
|
"dependencies": {
|
|
43
49
|
"execa": "^9.6.1"
|