or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-download.mdexceptions.mdextractor-system.mdindex.mdpost-processing.mdutilities.md

post-processing.mddocs/

0

# Post-Processing

1

2

Configurable pipeline of processors for audio extraction, video conversion, subtitle handling, metadata embedding, and other file transformations applied after download. The post-processing system provides extensive capabilities for format conversion, quality optimization, and content enhancement.

3

4

## Capabilities

5

6

### FFmpeg Audio Processing

7

8

Post-processors for audio extraction, conversion, and quality optimization using FFmpeg.

9

10

```python { .api }

11

class FFmpegExtractAudioPP:

12

"""

13

Extract audio from video files using FFmpeg.

14

15

Supports various audio formats and quality settings,

16

with automatic codec selection and quality optimization.

17

"""

18

19

def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, nopostoverwrites=False):

20

"""

21

Initialize audio extraction post-processor.

22

23

Parameters:

24

- downloader: YoutubeDL instance

25

- preferredcodec: str|None, preferred audio codec ('mp3', 'aac', 'flac', etc.)

26

- preferredquality: str|None, quality setting ('0'-'9' for VBR, or bitrate)

27

- nopostoverwrites: bool, don't overwrite existing files

28

"""

29

30

class FFmpegPostProcessor:

31

"""

32

Base class for FFmpeg-based post-processors.

33

34

Provides common functionality for running FFmpeg commands,

35

handling options, and managing temporary files.

36

"""

37

38

def __init__(self, downloader=None):

39

"""

40

Initialize FFmpeg post-processor.

41

42

Parameters:

43

- downloader: YoutubeDL instance

44

"""

45

46

def run_ffmpeg(self, path, out_path, opts):

47

"""

48

Run FFmpeg command with specified options.

49

50

Parameters:

51

- path: str, input file path

52

- out_path: str, output file path

53

- opts: list[str], FFmpeg options

54

"""

55

56

def run_ffmpeg_multiple_files(self, input_paths, out_path, opts):

57

"""

58

Run FFmpeg with multiple input files.

59

60

Parameters:

61

- input_paths: list[str], input file paths

62

- out_path: str, output file path

63

- opts: list[str], FFmpeg options

64

"""

65

```

66

67

### FFmpeg Video Processing

68

69

Post-processors for video format conversion, quality adjustment, and container remuxing.

70

71

```python { .api }

72

class FFmpegVideoConvertorPP(FFmpegPostProcessor):

73

"""

74

Convert video files to different formats using FFmpeg.

75

76

Supports various video codecs, quality settings, and container formats

77

with automatic parameter optimization for different use cases.

78

"""

79

80

def __init__(self, downloader=None, preferedformat=None):

81

"""

82

Initialize video conversion post-processor.

83

84

Parameters:

85

- downloader: YoutubeDL instance

86

- preferedformat: str|None, preferred output format ('mp4', 'mkv', 'webm', etc.)

87

"""

88

89

class FFmpegVideoRemuxerPP(FFmpegPostProcessor):

90

"""

91

Remux video files to different containers without re-encoding.

92

93

Changes container format while preserving original video and audio streams,

94

providing fast conversion with no quality loss.

95

"""

96

97

def __init__(self, downloader=None, preferedformat=None):

98

"""

99

Initialize video remuxing post-processor.

100

101

Parameters:

102

- downloader: YoutubeDL instance

103

- preferedformat: str|None, preferred container format

104

"""

105

106

class FFmpegMergerPP(FFmpegPostProcessor):

107

"""

108

Merge separate video and audio files using FFmpeg.

109

110

Combines video-only and audio-only streams into single files,

111

commonly used for high-quality YouTube formats.

112

"""

113

114

def __init__(self, downloader=None):

115

"""Initialize merger post-processor."""

116

```

117

118

### Subtitle and Thumbnail Processing

119

120

Post-processors for handling subtitles, captions, and thumbnail images.

121

122

```python { .api }

123

class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):

124

"""

125

Convert subtitle files to different formats using FFmpeg.

126

127

Supports conversion between various subtitle formats including

128

SRT, VTT, ASS, and others with proper encoding handling.

129

"""

130

131

def __init__(self, downloader=None, format=None):

132

"""

133

Initialize subtitle conversion post-processor.

134

135

Parameters:

136

- downloader: YoutubeDL instance

137

- format: str|None, target subtitle format ('srt', 'vtt', 'ass', etc.)

138

"""

139

140

class FFmpegThumbnailsConvertorPP(FFmpegPostProcessor):

141

"""

142

Convert thumbnail images to different formats using FFmpeg.

143

144

Handles format conversion, resizing, and quality optimization

145

for thumbnail images.

146

"""

147

148

def __init__(self, downloader=None, format=None):

149

"""

150

Initialize thumbnail conversion post-processor.

151

152

Parameters:

153

- downloader: YoutubeDL instance

154

- format: str|None, target image format ('jpg', 'png', 'webp', etc.)

155

"""

156

157

class EmbedThumbnailPP:

158

"""

159

Embed thumbnail images into media files.

160

161

Adds thumbnail images as embedded artwork in supported

162

container formats like MP4, MKV, and MP3.

163

"""

164

165

def __init__(self, downloader=None, already_have_thumbnail=False):

166

"""

167

Initialize thumbnail embedding post-processor.

168

169

Parameters:

170

- downloader: YoutubeDL instance

171

- already_have_thumbnail: bool, whether thumbnail file already exists

172

"""

173

```

174

175

### Metadata Processing

176

177

Post-processors for parsing, extracting, and embedding metadata information.

178

179

```python { .api }

180

class FFmpegMetadataPP(FFmpegPostProcessor):

181

"""

182

Embed metadata into media files using FFmpeg.

183

184

Adds title, artist, album, date, and other metadata

185

to media files in supported container formats.

186

"""

187

188

def __init__(self, downloader=None, add_chapters=True, add_metadata=True, add_infojson=None):

189

"""

190

Initialize metadata embedding post-processor.

191

192

Parameters:

193

- downloader: YoutubeDL instance

194

- add_chapters: bool, add chapter information

195

- add_metadata: bool, add basic metadata

196

- add_infojson: bool|str|None, embed info JSON ('if_exists', True, False, None)

197

"""

198

199

class MetadataFromFieldPP:

200

"""

201

Extract metadata from existing fields using regex patterns.

202

203

Parses title, description, or other fields to extract

204

structured metadata like artist, album, track number.

205

"""

206

207

def __init__(self, downloader=None, actions=None):

208

"""

209

Initialize field-based metadata extraction.

210

211

Parameters:

212

- downloader: YoutubeDL instance

213

- actions: list[tuple], parsing actions to perform

214

"""

215

216

@staticmethod

217

def to_action(f):

218

"""

219

Convert field specification to action tuple.

220

221

Parameters:

222

- f: str, field specification string

223

224

Returns:

225

tuple: action specification

226

"""

227

228

class MetadataParserPP:

229

"""

230

Advanced metadata parsing and manipulation post-processor.

231

232

Provides sophisticated metadata parsing, replacement,

233

and transformation capabilities using various methods.

234

"""

235

236

def __init__(self, downloader=None, actions=None, when=None):

237

"""

238

Initialize metadata parser post-processor.

239

240

Parameters:

241

- downloader: YoutubeDL instance

242

- actions: list[tuple], parsing actions

243

- when: str|None, when to run processor

244

"""

245

246

@staticmethod

247

def validate_action(*action):

248

"""

249

Validate action specification.

250

251

Parameters:

252

- *action: action components

253

254

Raises:

255

ValueError: if action is invalid

256

"""

257

```

258

259

### Specialized Processing

260

261

Post-processors for specialized tasks like SponsorBlock integration and file operations.

262

263

```python { .api }

264

class SponsorBlockPP:

265

"""

266

SponsorBlock integration for marking/removing sponsored segments.

267

268

Integrates with SponsorBlock API to identify and handle

269

sponsored content, intros, outros, and other segments.

270

"""

271

272

def __init__(self, downloader=None, categories=None, api=None, when=None):

273

"""

274

Initialize SponsorBlock post-processor.

275

276

Parameters:

277

- downloader: YoutubeDL instance

278

- categories: set|None, segment categories to process

279

- api: str|None, SponsorBlock API URL

280

- when: str|None, when to run processor

281

"""

282

283

class ModifyChaptersPP:

284

"""

285

Modify chapter information in media files.

286

287

Adds, removes, or modifies chapters based on patterns,

288

SponsorBlock data, or custom specifications.

289

"""

290

291

def __init__(self, downloader=None, remove_chapters_patterns=None, remove_sponsor_segments=None, remove_ranges=None, sponsorblock_chapter_title=None, force_keyframes=False):

292

"""

293

Initialize chapter modification post-processor.

294

295

Parameters:

296

- downloader: YoutubeDL instance

297

- remove_chapters_patterns: list|None, patterns for chapters to remove

298

- remove_sponsor_segments: set|None, sponsor segment types to remove

299

- remove_ranges: list|None, time ranges to remove

300

- sponsorblock_chapter_title: str|None, title template for SponsorBlock chapters

301

- force_keyframes: bool, force keyframes at cuts

302

"""

303

304

class XAttrMetadataPP:

305

"""

306

Store metadata in file extended attributes (xattrs).

307

308

Saves metadata information in filesystem extended attributes

309

for preservation across file operations.

310

"""

311

312

def __init__(self, downloader=None):

313

"""Initialize extended attributes post-processor."""

314

315

class MoveFilesAfterDownloadPP:

316

"""

317

Move files to different locations after processing.

318

319

Handles file relocation based on templates and patterns,

320

useful for organizing downloads into directory structures.

321

"""

322

323

def __init__(self, downloader=None):

324

"""Initialize file moving post-processor."""

325

```

326

327

### Post-Processor Management

328

329

Functions for discovering and managing post-processors.

330

331

```python { .api }

332

def get_postprocessor(key):

333

"""

334

Get post-processor class by key name.

335

336

Parameters:

337

- key: str, post-processor identifier

338

339

Returns:

340

type: post-processor class

341

342

Raises:

343

KeyError: if post-processor not found

344

"""

345

```

346

347

## Usage Examples

348

349

### Audio Extraction

350

351

```python

352

import yt_dlp

353

354

# Extract MP3 audio at high quality

355

ydl_opts = {

356

'format': 'bestaudio/best',

357

'postprocessors': [{

358

'key': 'FFmpegExtractAudio',

359

'preferredcodec': 'mp3',

360

'preferredquality': '192',

361

}],

362

}

363

364

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

365

ydl.download(['https://www.youtube.com/watch?v=example'])

366

```

367

368

### Video Format Conversion

369

370

```python

371

import yt_dlp

372

373

# Convert to MP4 with specific quality

374

ydl_opts = {

375

'format': 'best[height<=720]',

376

'postprocessors': [{

377

'key': 'FFmpegVideoConvertor',

378

'preferedformat': 'mp4',

379

}],

380

}

381

382

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

383

ydl.download(['https://www.youtube.com/watch?v=example'])

384

```

385

386

### Metadata Embedding

387

388

```python

389

import yt_dlp

390

391

# Embed metadata and thumbnail

392

ydl_opts = {

393

'writethumbnail': True,

394

'postprocessors': [

395

{

396

'key': 'FFmpegMetadata',

397

'add_metadata': True,

398

'add_chapters': True,

399

},

400

{

401

'key': 'EmbedThumbnail',

402

'already_have_thumbnail': False,

403

},

404

],

405

}

406

407

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

408

ydl.download(['https://www.youtube.com/watch?v=example'])

409

```

410

411

### Subtitle Processing

412

413

```python

414

import yt_dlp

415

416

# Download and convert subtitles to SRT

417

ydl_opts = {

418

'writesubtitles': True,

419

'writeautomaticsub': True,

420

'subtitleslangs': ['en', 'es'],

421

'postprocessors': [{

422

'key': 'FFmpegSubtitlesConvertor',

423

'format': 'srt',

424

}],

425

}

426

427

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

428

ydl.download(['https://www.youtube.com/watch?v=example'])

429

```

430

431

### Custom Processing Pipeline

432

433

```python

434

import yt_dlp

435

436

# Complex processing pipeline

437

ydl_opts = {

438

'format': 'best',

439

'writethumbnail': True,

440

'writesubtitles': True,

441

'postprocessors': [

442

# First: Convert subtitles

443

{

444

'key': 'FFmpegSubtitlesConvertor',

445

'format': 'srt',

446

},

447

# Second: Extract audio

448

{

449

'key': 'FFmpegExtractAudio',

450

'preferredcodec': 'mp3',

451

'preferredquality': '192',

452

},

453

# Third: Embed metadata

454

{

455

'key': 'FFmpegMetadata',

456

'add_metadata': True,

457

},

458

# Fourth: Embed thumbnail

459

{

460

'key': 'EmbedThumbnail',

461

},

462

# Fifth: Store in extended attributes

463

{

464

'key': 'XAttrMetadata',

465

},

466

],

467

}

468

469

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

470

ydl.download(['https://www.youtube.com/watch?v=example'])

471

```

472

473

### SponsorBlock Integration

474

475

```python

476

import yt_dlp

477

478

# Remove sponsored segments using SponsorBlock

479

ydl_opts = {

480

'postprocessors': [{

481

'key': 'SponsorBlock',

482

'categories': ['sponsor', 'intro', 'outro'],

483

'api': 'https://sponsor.ajay.app',

484

'when': 'after_filter',

485

}],

486

}

487

488

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

489

ydl.download(['https://www.youtube.com/watch?v=example'])

490

```

491

492

### Custom Post-Processor

493

494

```python

495

import yt_dlp

496

from yt_dlp.postprocessor import PostProcessor

497

498

class CustomPP(PostProcessor):

499

def __init__(self, downloader=None):

500

super().__init__(downloader)

501

502

def run(self, info):

503

# Custom processing logic

504

filename = info['filepath']

505

self.to_screen(f'Custom processing: {filename}')

506

507

# Return updated info and files to delete

508

return [], info

509

510

# Use custom post-processor

511

ydl_opts = {

512

'postprocessors': [{'key': 'Custom'}],

513

}

514

515

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

516

# Register custom post-processor

517

ydl.add_post_processor(CustomPP())

518

ydl.download(['https://www.youtube.com/watch?v=example'])

519

```

520

521

## Types

522

523

```python { .api }

524

# Base post-processor class

525

class PostProcessor:

526

def __init__(self, downloader=None): ...

527

def run(self, info): ...

528

def to_screen(self, message, skip_eol=False): ...

529

530

# Post-processor configuration dictionary

531

PostProcessorDict = dict[str, Any]

532

533

# Processing phases when post-processors can run

534

POSTPROCESS_WHEN = [

535

'pre_process', # Before extraction

536

'after_filter', # After filtering but before download

537

'before_dl', # Before download

538

'post_process', # After download (default)

539

'after_move', # After moving files

540

'after_video', # After video processing

541

'playlist', # After playlist processing

542

]

543

```