0
# Format Selection
1
2
Advanced format selection utilities for choosing optimal video and audio formats based on quality, codec, and container preferences. Provides both automated selection and manual filtering capabilities.
3
4
## Capabilities
5
6
### Choose Format
7
8
Automatically selects the best format from available options based on specified criteria.
9
10
```javascript { .api }
11
/**
12
* Chooses the best format from available formats based on criteria
13
* @param {videoFormat | videoFormat[]} formats - Available formats or single format
14
* @param {chooseFormatOptions} options - Selection criteria
15
* @returns {videoFormat} - Selected format
16
* @throws {Error} - If no matching format found
17
*/
18
function chooseFormat(formats, options);
19
20
interface chooseFormatOptions {
21
quality?: string | number | string[] | number[]; // Quality preference
22
filter?: string | function; // Format filter
23
format?: videoFormat; // Specific format to use
24
}
25
```
26
27
**Usage Examples:**
28
29
```javascript
30
const info = await ytdl.getInfo(videoUrl);
31
32
// Choose highest quality format (default)
33
const format = ytdl.chooseFormat(info.formats, { quality: 'highest' });
34
35
// Choose by quality string
36
const audioFormat = ytdl.chooseFormat(info.formats, { quality: 'highestaudio' });
37
const videoFormat = ytdl.chooseFormat(info.formats, { quality: 'highestvideo' });
38
39
// Choose by itag number
40
const specificFormat = ytdl.chooseFormat(info.formats, { quality: 140 });
41
42
// Choose from multiple quality options (first available wins)
43
const format = ytdl.chooseFormat(info.formats, {
44
quality: ['highestvideo', 'highest', 140]
45
});
46
47
// Choose with filter
48
const mp4Format = ytdl.chooseFormat(info.formats, {
49
quality: 'highest',
50
filter: 'audioandvideo'
51
});
52
53
// Use custom filter function
54
const customFormat = ytdl.chooseFormat(info.formats, {
55
filter: format => format.container === 'mp4' && format.hasAudio
56
});
57
```
58
59
### Filter Formats
60
61
Filters available formats based on specific criteria, useful for examining available options before selection.
62
63
```javascript { .api }
64
/**
65
* Filters formats based on criteria
66
* @param {videoFormat | videoFormat[]} formats - Formats to filter
67
* @param {string | function} filter - Filter criteria or custom function
68
* @returns {videoFormat[]} - Filtered formats array
69
*/
70
function filterFormats(formats, filter);
71
```
72
73
**Usage Examples:**
74
75
```javascript
76
const info = await ytdl.getInfo(videoUrl);
77
78
// Filter for audio-only formats
79
const audioFormats = ytdl.filterFormats(info.formats, 'audioonly');
80
console.log(`Audio formats: ${audioFormats.length}`);
81
82
// Filter for video-only formats
83
const videoFormats = ytdl.filterFormats(info.formats, 'videoonly');
84
85
// Filter for formats with both audio and video
86
const combinedFormats = ytdl.filterFormats(info.formats, 'audioandvideo');
87
88
// Custom filter function
89
const mp4Formats = ytdl.filterFormats(info.formats, format => {
90
return format.container === 'mp4' && format.bitrate > 1000000;
91
});
92
93
// Filter for HD formats
94
const hdFormats = ytdl.filterFormats(info.formats, format => {
95
return format.height && format.height >= 720;
96
});
97
```
98
99
## Quality Options
100
101
### Predefined Quality Strings
102
103
```javascript { .api }
104
type ChooseFormatQuality =
105
| 'lowest' // Lowest quality format
106
| 'highest' // Highest quality format (default)
107
| 'highestaudio' // Best audio quality (minimizes video bitrate)
108
| 'lowestaudio' // Lowest audio quality
109
| 'highestvideo' // Best video quality (minimizes audio bitrate)
110
| 'lowestvideo'; // Lowest video quality
111
112
type VideoFormatQuality =
113
| 'tiny' | 'small' | 'medium' | 'large'
114
| 'hd720' | 'hd1080' | 'hd1440' | 'hd2160' | 'highres';
115
116
// Utility type to extend string types while preserving auto-completion
117
type ExtendString<T extends string> = T | Omit<string, T>;
118
```
119
120
**Quality Selection Behavior:**
121
122
```javascript
123
// 'highest' - Prefers formats with both audio and video, highest bitrate
124
const format = ytdl.chooseFormat(formats, { quality: 'highest' });
125
126
// 'highestaudio' - Best audio quality, worst video quality for that audio
127
const format = ytdl.chooseFormat(formats, { quality: 'highestaudio' });
128
129
// 'highestvideo' - Best video quality, worst audio quality for that video
130
const format = ytdl.chooseFormat(formats, { quality: 'highestvideo' });
131
```
132
133
### Itag-based Selection
134
135
YouTube formats are identified by itag numbers. You can specify exact formats:
136
137
```javascript
138
// Common itag examples:
139
// 18 - 360p MP4 with audio (avc1.42001E, mp4a.40.2)
140
// 140 - Audio-only M4A (mp4a.40.2) ~128kbps
141
// 137 - 1080p MP4 video-only (avc1.640028)
142
// 248 - 1080p WebM video-only (vp9)
143
144
const format = ytdl.chooseFormat(formats, { quality: 140 }); // Audio-only M4A
145
const format = ytdl.chooseFormat(formats, { quality: [137, 248, 'highest'] }); // Prefer 1080p, fallback
146
```
147
148
## Filter Options
149
150
### Predefined Filter Strings
151
152
```javascript { .api }
153
type Filter =
154
| 'audioandvideo' // Formats with both audio and video
155
| 'videoandaudio' // Same as audioandvideo
156
| 'video' // Formats containing video (may also have audio)
157
| 'videoonly' // Formats with video but no audio
158
| 'audio' // Formats containing audio (may also have video)
159
| 'audioonly' // Formats with audio but no video
160
| function; // Custom filter function
161
```
162
163
**Filter Examples:**
164
165
```javascript
166
// Get only formats with both audio and video
167
const combined = ytdl.filterFormats(formats, 'audioandvideo');
168
169
// Get video-only formats (for merging with separate audio)
170
const videoOnly = ytdl.filterFormats(formats, 'videoonly');
171
172
// Get audio-only formats
173
const audioOnly = ytdl.filterFormats(formats, 'audioonly');
174
175
// Custom filter for specific containers
176
const webmFormats = ytdl.filterFormats(formats, format => format.container === 'webm');
177
```
178
179
### Custom Filter Functions
180
181
Filter functions receive a format object and should return boolean:
182
183
```javascript { .api }
184
/**
185
* Custom filter function
186
* @param {videoFormat} format - Format to evaluate
187
* @param {number} index - Index in formats array
188
* @param {videoFormat[]} formats - Full formats array
189
* @returns {boolean} - Whether to include this format
190
*/
191
function customFilter(format, index, formats);
192
```
193
194
**Custom Filter Examples:**
195
196
```javascript
197
// Filter for high-quality MP4 formats
198
const hqMp4 = ytdl.filterFormats(formats, format => {
199
return format.container === 'mp4' &&
200
format.height >= 720 &&
201
format.hasAudio;
202
});
203
204
// Filter for formats with specific codecs
205
const h264Formats = ytdl.filterFormats(formats, format => {
206
return format.videoCodec && format.videoCodec.includes('avc1');
207
});
208
209
// Filter for live stream formats
210
const liveFormats = ytdl.filterFormats(formats, format => format.isLive);
211
212
// Filter by file size (approximate)
213
const smallFormats = ytdl.filterFormats(formats, format => {
214
const sizeEstimate = parseInt(format.contentLength) || 0;
215
return sizeEstimate < 50 * 1024 * 1024; // Under 50MB
216
});
217
```
218
219
## Format Sorting and Prioritization
220
221
Formats are automatically sorted by ytdl-core using these criteria (highest priority first):
222
223
1. **Video Encoding Quality**: H.264 > VP9 > VP8 > older codecs
224
2. **Video Bitrate**: Higher bitrate preferred
225
3. **Audio Encoding Quality**: FLAC > Opus > AAC > Vorbis > MP3 > older codecs
226
4. **Audio Bitrate**: Higher bitrate preferred
227
5. **Resolution**: Higher resolution preferred
228
229
## Advanced Selection Patterns
230
231
### Separate Audio and Video Streams
232
233
For highest quality, download separate audio and video streams and merge with ffmpeg:
234
235
```javascript
236
const info = await ytdl.getInfo(videoUrl);
237
238
// Get best video-only format
239
const videoFormat = ytdl.chooseFormat(info.formats, {
240
quality: 'highestvideo',
241
filter: 'videoonly'
242
});
243
244
// Get best audio-only format
245
const audioFormat = ytdl.chooseFormat(info.formats, {
246
quality: 'highestaudio',
247
filter: 'audioonly'
248
});
249
250
// Download both streams
251
const videoStream = ytdl.downloadFromInfo(info, { format: videoFormat });
252
const audioStream = ytdl.downloadFromInfo(info, { format: audioFormat });
253
254
// Merge with ffmpeg (external process)
255
```
256
257
### Adaptive Quality Selection
258
259
Choose formats based on available bandwidth or device capabilities:
260
261
```javascript
262
function chooseAdaptiveFormat(formats, maxBitrate) {
263
const suitableFormats = ytdl.filterFormats(formats, format => {
264
return format.hasAudio && format.hasVideo &&
265
(format.bitrate || 0) <= maxBitrate;
266
});
267
268
return ytdl.chooseFormat(suitableFormats, { quality: 'highest' });
269
}
270
271
// For mobile devices or slow connections
272
const mobileFormat = chooseAdaptiveFormat(info.formats, 1000000); // 1Mbps max
273
```
274
275
### Container-specific Selection
276
277
Choose formats based on container requirements:
278
279
```javascript
280
// Prefer MP4 for better compatibility
281
const mp4Format = ytdl.chooseFormat(info.formats, {
282
quality: 'highest',
283
filter: format => format.container === 'mp4'
284
});
285
286
// WebM for web streaming
287
const webmFormat = ytdl.chooseFormat(info.formats, {
288
quality: 'highest',
289
filter: format => format.container === 'webm'
290
});
291
```
292
293
### Live Stream Handling
294
295
Live streams require special format handling:
296
297
```javascript
298
const info = await ytdl.getInfo(liveVideoUrl);
299
300
// Filter for HLS formats (required for live streams)
301
const liveFormats = ytdl.filterFormats(info.formats, format => format.isHLS);
302
303
if (liveFormats.length > 0) {
304
const format = ytdl.chooseFormat(liveFormats, { quality: 'highest' });
305
const stream = ytdl.downloadFromInfo(info, {
306
format,
307
begin: Date.now(), // Start from current time
308
liveBuffer: 30000 // 30 second buffer
309
});
310
}
311
```
312
313
## Error Handling
314
315
Common format selection errors and solutions:
316
317
```javascript
318
try {
319
const format = ytdl.chooseFormat(info.formats, options);
320
} catch (error) {
321
if (error.message.includes('No such format found')) {
322
console.log('Requested format not available');
323
324
// Fallback to any available format
325
const fallbackFormat = ytdl.chooseFormat(info.formats, { quality: 'highest' });
326
327
// Or list available formats
328
console.log('Available formats:');
329
info.formats.forEach(f => {
330
console.log(`${f.itag}: ${f.qualityLabel} ${f.container}`);
331
});
332
}
333
}
334
```