0
# Post-Processors
1
2
Post-processors handle media processing tasks after download completion, including format conversion, audio extraction, subtitle handling, metadata manipulation, and file system operations.
3
4
## Capabilities
5
6
### Audio Processing
7
8
FFmpeg-based audio extraction and conversion with support for multiple codecs and quality settings.
9
10
```python { .api }
11
class FFmpegExtractAudioPP:
12
def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, nopostoverwrites=False):
13
"""
14
Extract audio from video files.
15
16
Parameters:
17
- downloader: YoutubeDL instance
18
- preferredcodec (str): Output audio codec ('mp3', 'aac', 'flac', 'vorbis', 'wav', 'opus', 'm4a')
19
- preferredquality (str): Audio quality (bitrate or quality level)
20
- nopostoverwrites (bool): Don't overwrite existing post-processed files
21
"""
22
23
def run(self, information):
24
"""
25
Run the audio extraction process.
26
27
Parameters:
28
- information (dict): Video information dictionary
29
30
Returns:
31
tuple: (information_dict, files_to_delete)
32
"""
33
```
34
35
### Video Conversion
36
37
Video format conversion and re-encoding using FFmpeg.
38
39
```python { .api }
40
class FFmpegVideoConvertorPP:
41
def __init__(self, downloader=None, preferedformat=None):
42
"""
43
Convert video files to different formats.
44
45
Parameters:
46
- downloader: YoutubeDL instance
47
- preferedformat (str): Target video format ('mp4', 'flv', 'ogg', 'webm', 'mkv', 'avi')
48
"""
49
50
def run(self, information):
51
"""
52
Run the video conversion process.
53
54
Parameters:
55
- information (dict): Video information dictionary
56
57
Returns:
58
tuple: (information_dict, files_to_delete)
59
"""
60
```
61
62
### Subtitle Processing
63
64
Subtitle embedding and format conversion capabilities.
65
66
```python { .api }
67
class FFmpegEmbedSubtitlePP:
68
def __init__(self, downloader=None, subtitlesformat='srt'):
69
"""
70
Embed subtitle tracks into video files.
71
72
Parameters:
73
- downloader: YoutubeDL instance
74
- subtitlesformat (str): Subtitle format ('srt', 'vtt', 'ass')
75
"""
76
77
def run(self, information):
78
"""
79
Embed subtitles into video file.
80
81
Parameters:
82
- information (dict): Video information with subtitle files
83
84
Returns:
85
tuple: (information_dict, files_to_delete)
86
"""
87
88
class FFmpegSubtitlesConvertorPP:
89
def __init__(self, downloader=None, format=None):
90
"""
91
Convert subtitles between formats.
92
93
Parameters:
94
- downloader: YoutubeDL instance
95
- format (str): Target subtitle format ('srt', 'vtt', 'ass', 'lrc')
96
"""
97
98
def run(self, information):
99
"""
100
Convert subtitle files to target format.
101
102
Parameters:
103
- information (dict): Video information with subtitle files
104
105
Returns:
106
tuple: (information_dict, files_to_delete)
107
"""
108
```
109
110
### Metadata Processing
111
112
Metadata extraction, manipulation, and embedding capabilities.
113
114
```python { .api }
115
class FFmpegMetadataPP:
116
def __init__(self, downloader=None):
117
"""
118
Add metadata to media files using FFmpeg.
119
120
Parameters:
121
- downloader: YoutubeDL instance
122
"""
123
124
def run(self, information):
125
"""
126
Add metadata to the media file.
127
128
Parameters:
129
- information (dict): Video information with metadata
130
131
Returns:
132
tuple: (information_dict, files_to_delete)
133
"""
134
135
class MetadataFromTitlePP:
136
def __init__(self, downloader=None, titleformat=None):
137
"""
138
Extract metadata from video title using regex.
139
140
Parameters:
141
- downloader: YoutubeDL instance
142
- titleformat (str): Regex pattern for title parsing
143
"""
144
145
def run(self, information):
146
"""
147
Extract metadata from title.
148
149
Parameters:
150
- information (dict): Video information dictionary
151
152
Returns:
153
tuple: (information_dict, files_to_delete)
154
"""
155
```
156
157
### Thumbnail Processing
158
159
Thumbnail embedding and manipulation functionality.
160
161
```python { .api }
162
class EmbedThumbnailPP:
163
def __init__(self, downloader=None, already_have_thumbnail=False):
164
"""
165
Embed thumbnail image into media files.
166
167
Parameters:
168
- downloader: YoutubeDL instance
169
- already_have_thumbnail (bool): Whether thumbnail was already downloaded
170
"""
171
172
def run(self, information):
173
"""
174
Embed thumbnail into media file.
175
176
Parameters:
177
- information (dict): Video information with thumbnail
178
179
Returns:
180
tuple: (information_dict, files_to_delete)
181
"""
182
```
183
184
### File System Operations
185
186
File system and extended attribute processing.
187
188
```python { .api }
189
class XAttrMetadataPP:
190
def __init__(self, downloader=None):
191
"""
192
Write metadata to extended file attributes.
193
194
Parameters:
195
- downloader: YoutubeDL instance
196
"""
197
198
def run(self, information):
199
"""
200
Write metadata to file extended attributes.
201
202
Parameters:
203
- information (dict): Video information with metadata
204
205
Returns:
206
tuple: (information_dict, files_to_delete)
207
"""
208
209
class ExecAfterDownloadPP:
210
def __init__(self, downloader=None, exec_cmd=None):
211
"""
212
Execute custom command after download completion.
213
214
Parameters:
215
- downloader: YoutubeDL instance
216
- exec_cmd (str): Command to execute with filename
217
"""
218
219
def run(self, information):
220
"""
221
Execute the configured command.
222
223
Parameters:
224
- information (dict): Video information dictionary
225
226
Returns:
227
tuple: (information_dict, files_to_delete)
228
"""
229
```
230
231
### Base PostProcessor Class
232
233
Base class that all post-processors inherit from.
234
235
```python { .api }
236
class PostProcessor:
237
def __init__(self, downloader=None):
238
"""
239
Base post-processor class.
240
241
Parameters:
242
- downloader: YoutubeDL instance
243
"""
244
245
def set_downloader(self, downloader):
246
"""
247
Set the downloader instance.
248
249
Parameters:
250
- downloader: YoutubeDL instance
251
"""
252
253
def run(self, information):
254
"""
255
Run the post-processing operation.
256
257
Parameters:
258
- information (dict): Video information dictionary
259
260
Returns:
261
tuple: (information_dict, files_to_delete)
262
"""
263
264
def try_utime(self, path, atime, mtime, errnote='Cannot update utime of file'):
265
"""
266
Try to update file access and modification times.
267
268
Parameters:
269
- path (str): File path
270
- atime (float): Access time
271
- mtime (float): Modification time
272
- errnote (str): Error message if operation fails
273
"""
274
```
275
276
## Post-Processor Configuration
277
278
Post-processors are configured through the YoutubeDL params dictionary using the `postprocessors` key:
279
280
```python
281
postprocessors = [
282
{
283
'key': 'FFmpegExtractAudio',
284
'preferredcodec': 'mp3',
285
'preferredquality': '192',
286
'nopostoverwrites': False,
287
},
288
{
289
'key': 'FFmpegVideoConvertor',
290
'preferedformat': 'mp4',
291
},
292
{
293
'key': 'FFmpegMetadata',
294
},
295
{
296
'key': 'EmbedThumbnail',
297
'already_have_thumbnail': False,
298
}
299
]
300
```
301
302
## Processing Order
303
304
Post-processors run in the order they are specified, with some considerations:
305
306
1. **FFmpegExtractAudio** and **FFmpegVideoConvertor** should run before metadata processors
307
2. **FFmpegMetadata** should run after format conversion but before subtitle embedding
308
3. **FFmpegEmbedSubtitle** should run after metadata processing
309
4. **XAttrMetadata** should run after content-changing processors
310
5. **ExecAfterDownload** should run last to allow user scripts to process final files
311
312
## Usage Examples
313
314
### Audio Extraction
315
```python
316
from youtube_dl import YoutubeDL
317
318
ydl_opts = {
319
'format': 'bestaudio/best',
320
'postprocessors': [{
321
'key': 'FFmpegExtractAudio',
322
'preferredcodec': 'mp3',
323
'preferredquality': '320',
324
}],
325
'keepvideo': False,
326
}
327
with YoutubeDL(ydl_opts) as ydl:
328
ydl.download(['https://www.youtube.com/watch?v=VIDEO_ID'])
329
```
330
331
### Video Conversion with Metadata
332
```python
333
ydl_opts = {
334
'postprocessors': [
335
{
336
'key': 'FFmpegVideoConvertor',
337
'preferedformat': 'mp4',
338
},
339
{
340
'key': 'FFmpegMetadata',
341
},
342
{
343
'key': 'EmbedThumbnail',
344
'already_have_thumbnail': False,
345
}
346
],
347
'writethumbnail': True,
348
}
349
with YoutubeDL(ydl_opts) as ydl:
350
ydl.download(['https://www.youtube.com/watch?v=VIDEO_ID'])
351
```
352
353
### Custom Command Execution
354
```python
355
ydl_opts = {
356
'postprocessors': [{
357
'key': 'ExecAfterDownload',
358
'exec_cmd': 'mv {} /final/destination/',
359
}],
360
}
361
with YoutubeDL(ydl_opts) as ydl:
362
ydl.download(['https://www.youtube.com/watch?v=VIDEO_ID'])
363
```
364
365
### Subtitle Processing
366
```python
367
ydl_opts = {
368
'writesubtitles': True,
369
'writeautomaticsub': True,
370
'subtitleslangs': ['en', 'es'],
371
'postprocessors': [
372
{
373
'key': 'FFmpegSubtitlesConvertor',
374
'format': 'srt',
375
},
376
{
377
'key': 'FFmpegEmbedSubtitle',
378
}
379
],
380
}
381
with YoutubeDL(ydl_opts) as ydl:
382
ydl.download(['https://www.youtube.com/watch?v=VIDEO_ID'])
383
```