0
# Video Downloading
1
2
Core streaming download functionality for YouTube videos with extensive configuration options, progress tracking, and support for various video formats including live streams.
3
4
## Capabilities
5
6
### Main Download Function
7
8
Downloads a YouTube video and returns a readable stream with comprehensive options for customization.
9
10
```javascript { .api }
11
/**
12
* Downloads a YouTube video and returns a readable stream
13
* @param {string} url - YouTube video URL or video ID
14
* @param {downloadOptions} options - Download configuration options
15
* @returns {stream.Readable} - Readable stream of video data
16
*/
17
function ytdl(url, options);
18
19
interface downloadOptions {
20
// Range options
21
range?: {
22
start?: number; // Start byte position
23
end?: number; // End byte position
24
};
25
26
// Timing options
27
begin?: string | number | Date; // Start time (e.g., '1:30', '05:10.123', '10m30s')
28
liveBuffer?: number; // Live stream buffer in milliseconds (default: 20000)
29
30
// Stream options
31
highWaterMark?: number; // Buffer size in bytes (default: 512KB)
32
dlChunkSize?: number; // Chunk size for video-only/audio-only downloads (default: 10MB, 0 to disable)
33
34
// Network options
35
IPv6Block?: string; // IPv6 block for request rotation
36
requestOptions?: object; // Options passed to miniget
37
requestCallback?: function; // Callback for request streams
38
39
// Format selection (inherited from chooseFormatOptions)
40
quality?: string | number | string[] | number[];
41
filter?: string | function;
42
format?: object;
43
44
// Info options (inherited from getInfoOptions)
45
lang?: string; // Language code (default: 'en')
46
}
47
```
48
49
**Usage Examples:**
50
51
```javascript
52
const ytdl = require('ytdl-core');
53
const fs = require('fs');
54
55
// Basic download
56
ytdl('https://www.youtube.com/watch?v=aqz-KE-bpKQ')
57
.pipe(fs.createWriteStream('video.mp4'));
58
59
// Download with range (bytes 1000-5000)
60
ytdl(videoUrl, {
61
range: { start: 1000, end: 5000 }
62
}).pipe(outputStream);
63
64
// Download starting from specific time
65
ytdl(videoUrl, {
66
begin: '1:30' // Start at 1 minute 30 seconds
67
}).pipe(outputStream);
68
69
// Download with specific quality
70
ytdl(videoUrl, {
71
quality: 'highestaudio'
72
}).pipe(outputStream);
73
74
// Download with IPv6 rotation
75
ytdl(videoUrl, {
76
IPv6Block: '2001:2::/48'
77
}).pipe(outputStream);
78
```
79
80
### Download from Pre-fetched Info
81
82
Downloads video using previously fetched video information, useful when you want to examine video details before downloading.
83
84
```javascript { .api }
85
/**
86
* Downloads video using pre-fetched info object
87
* @param {videoInfo} info - Video info from getInfo() (must have full: true)
88
* @param {downloadOptions} options - Download options
89
* @returns {stream.Readable} - Readable stream of video data
90
* @throws {Error} - If info is from getBasicInfo() (full: false)
91
*/
92
function downloadFromInfo(info, options);
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
// Get info first, then download
99
const info = await ytdl.getInfo(videoUrl);
100
console.log(`Downloading: ${info.videoDetails.title}`);
101
102
const stream = ytdl.downloadFromInfo(info, {
103
quality: 'highest'
104
});
105
stream.pipe(fs.createWriteStream('video.mp4'));
106
```
107
108
## Stream Events
109
110
The returned stream emits several events for monitoring download progress and handling responses.
111
112
### Event: 'info'
113
114
Emitted when video information is fetched and format is chosen.
115
116
```javascript { .api }
117
/**
118
* Emitted when video info is fetched and format is selected
119
* @param {videoInfo} info - Complete video information
120
* @param {videoFormat} format - Selected format for download
121
*/
122
stream.on('info', (info, format) => {
123
console.log(`Title: ${info.videoDetails.title}`);
124
console.log(`Format: ${format.qualityLabel} ${format.container}`);
125
});
126
```
127
128
### Event: 'progress'
129
130
Emitted during download to track progress.
131
132
```javascript { .api }
133
/**
134
* Emitted during download for progress tracking
135
* @param {number} chunkLength - Length of current chunk or segment number
136
* @param {number} downloaded - Total bytes downloaded or segments completed
137
* @param {number} total - Total bytes or total segments
138
*/
139
stream.on('progress', (chunkLength, downloaded, total) => {
140
const percent = downloaded / total * 100;
141
console.log(`Downloaded ${percent.toFixed(1)}%`);
142
});
143
```
144
145
### Miniget Events
146
147
All miniget request events are forwarded and can be listened to:
148
149
```javascript { .api }
150
// Network events forwarded from miniget
151
stream.on('request', (req) => { /* HTTP request started */ });
152
stream.on('response', (res) => { /* HTTP response received */ });
153
stream.on('redirect', (url) => { /* Request redirected */ });
154
stream.on('retry', (retryCount) => { /* Request retried */ });
155
stream.on('reconnect', (reconnectCount) => { /* Connection reconnected */ });
156
stream.on('abort', () => { /* Request aborted */ });
157
stream.on('error', (err) => { /* Error occurred */ });
158
```
159
160
## Stream Control
161
162
### Destroy Stream
163
164
Aborts and stops downloading a video.
165
166
```javascript { .api }
167
/**
168
* Aborts the download and destroys the stream
169
*/
170
stream.destroy();
171
```
172
173
**Usage Example:**
174
175
```javascript
176
const stream = ytdl(videoUrl);
177
stream.pipe(outputStream);
178
179
// Abort after 5 seconds
180
setTimeout(() => {
181
stream.destroy();
182
console.log('Download aborted');
183
}, 5000);
184
```
185
186
## Download Options Details
187
188
### Range Downloads
189
190
Specify byte ranges for partial content downloads (not supported for segmented formats).
191
192
```javascript
193
// Download first 1MB
194
ytdl(url, { range: { start: 0, end: 1024 * 1024 } })
195
196
// Download from 1MB onwards
197
ytdl(url, { range: { start: 1024 * 1024 } })
198
```
199
200
### Time-based Downloads
201
202
Start downloading from specific timestamps.
203
204
```javascript
205
// Various time formats supported
206
ytdl(url, { begin: '1:30' }) // 1 minute 30 seconds
207
ytdl(url, { begin: '05:10.123' }) // 5 minutes 10.123 seconds
208
ytdl(url, { begin: '10m30s' }) // 10 minutes 30 seconds
209
ytdl(url, { begin: 90000 }) // 90 seconds (milliseconds)
210
211
// For live videos, use Unix timestamp or Date
212
ytdl(liveUrl, { begin: Date.now() }) // Start from now
213
ytdl(liveUrl, { begin: new Date('2023-01-01T10:00:00Z') })
214
```
215
216
### IPv6 Block Rotation
217
218
Use IPv6 address rotation to avoid rate limiting.
219
220
```javascript
221
ytdl(url, {
222
IPv6Block: '2001:2::/48' // Rotates through IPv6 addresses in this block
223
})
224
```
225
226
### Chunked Downloads
227
228
Control download chunking for video-only or audio-only formats.
229
230
```javascript
231
ytdl(url, {
232
dlChunkSize: 1024 * 1024 * 5 // 5MB chunks (default: 10MB)
233
})
234
235
ytdl(url, {
236
dlChunkSize: 0 // Disable chunking
237
})
238
```
239
240
## Error Handling
241
242
Common errors and how to handle them:
243
244
```javascript
245
const stream = ytdl(url);
246
247
stream.on('error', (err) => {
248
if (err.message.includes('unavailable')) {
249
console.error('Video is unavailable');
250
} else if (err.message.includes('private')) {
251
console.error('Video is private');
252
} else if (err.statusCode === 429) {
253
console.error('Rate limited - try using proxies or IPv6 rotation');
254
} else {
255
console.error('Download error:', err.message);
256
}
257
});
258
```