CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-yt-dlp

A feature-rich command-line audio/video downloader forked from youtube-dl

Overview
Eval results
Files

post-processing.mddocs/

Post-Processing

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.

Capabilities

FFmpeg Audio Processing

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

class FFmpegExtractAudioPP:
    """
    Extract audio from video files using FFmpeg.
    
    Supports various audio formats and quality settings,
    with automatic codec selection and quality optimization.
    """
    
    def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, nopostoverwrites=False):
        """
        Initialize audio extraction post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - preferredcodec: str|None, preferred audio codec ('mp3', 'aac', 'flac', etc.)
        - preferredquality: str|None, quality setting ('0'-'9' for VBR, or bitrate)
        - nopostoverwrites: bool, don't overwrite existing files
        """

class FFmpegPostProcessor:
    """
    Base class for FFmpeg-based post-processors.
    
    Provides common functionality for running FFmpeg commands,
    handling options, and managing temporary files.
    """
    
    def __init__(self, downloader=None):
        """
        Initialize FFmpeg post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        """
    
    def run_ffmpeg(self, path, out_path, opts):
        """
        Run FFmpeg command with specified options.
        
        Parameters:
        - path: str, input file path
        - out_path: str, output file path  
        - opts: list[str], FFmpeg options
        """
    
    def run_ffmpeg_multiple_files(self, input_paths, out_path, opts):
        """
        Run FFmpeg with multiple input files.
        
        Parameters:
        - input_paths: list[str], input file paths
        - out_path: str, output file path
        - opts: list[str], FFmpeg options
        """

FFmpeg Video Processing

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

class FFmpegVideoConvertorPP(FFmpegPostProcessor):
    """
    Convert video files to different formats using FFmpeg.
    
    Supports various video codecs, quality settings, and container formats
    with automatic parameter optimization for different use cases.
    """
    
    def __init__(self, downloader=None, preferedformat=None):
        """
        Initialize video conversion post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - preferedformat: str|None, preferred output format ('mp4', 'mkv', 'webm', etc.)
        """

class FFmpegVideoRemuxerPP(FFmpegPostProcessor):
    """
    Remux video files to different containers without re-encoding.
    
    Changes container format while preserving original video and audio streams,
    providing fast conversion with no quality loss.
    """
    
    def __init__(self, downloader=None, preferedformat=None):
        """
        Initialize video remuxing post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - preferedformat: str|None, preferred container format
        """

class FFmpegMergerPP(FFmpegPostProcessor):
    """
    Merge separate video and audio files using FFmpeg.
    
    Combines video-only and audio-only streams into single files,
    commonly used for high-quality YouTube formats.
    """
    
    def __init__(self, downloader=None):
        """Initialize merger post-processor."""

Subtitle and Thumbnail Processing

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

class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
    """
    Convert subtitle files to different formats using FFmpeg.
    
    Supports conversion between various subtitle formats including
    SRT, VTT, ASS, and others with proper encoding handling.
    """
    
    def __init__(self, downloader=None, format=None):
        """
        Initialize subtitle conversion post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - format: str|None, target subtitle format ('srt', 'vtt', 'ass', etc.)
        """

class FFmpegThumbnailsConvertorPP(FFmpegPostProcessor):
    """
    Convert thumbnail images to different formats using FFmpeg.
    
    Handles format conversion, resizing, and quality optimization
    for thumbnail images.
    """
    
    def __init__(self, downloader=None, format=None):
        """
        Initialize thumbnail conversion post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - format: str|None, target image format ('jpg', 'png', 'webp', etc.)
        """

class EmbedThumbnailPP:
    """
    Embed thumbnail images into media files.
    
    Adds thumbnail images as embedded artwork in supported
    container formats like MP4, MKV, and MP3.
    """
    
    def __init__(self, downloader=None, already_have_thumbnail=False):
        """
        Initialize thumbnail embedding post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - already_have_thumbnail: bool, whether thumbnail file already exists
        """

Metadata Processing

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

class FFmpegMetadataPP(FFmpegPostProcessor):
    """
    Embed metadata into media files using FFmpeg.
    
    Adds title, artist, album, date, and other metadata
    to media files in supported container formats.
    """
    
    def __init__(self, downloader=None, add_chapters=True, add_metadata=True, add_infojson=None):
        """
        Initialize metadata embedding post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - add_chapters: bool, add chapter information
        - add_metadata: bool, add basic metadata
        - add_infojson: bool|str|None, embed info JSON ('if_exists', True, False, None)
        """

class MetadataFromFieldPP:
    """
    Extract metadata from existing fields using regex patterns.
    
    Parses title, description, or other fields to extract
    structured metadata like artist, album, track number.
    """
    
    def __init__(self, downloader=None, actions=None):
        """
        Initialize field-based metadata extraction.
        
        Parameters:
        - downloader: YoutubeDL instance
        - actions: list[tuple], parsing actions to perform
        """
    
    @staticmethod
    def to_action(f):
        """
        Convert field specification to action tuple.
        
        Parameters:
        - f: str, field specification string
        
        Returns:
        tuple: action specification
        """

class MetadataParserPP:
    """
    Advanced metadata parsing and manipulation post-processor.
    
    Provides sophisticated metadata parsing, replacement,
    and transformation capabilities using various methods.
    """
    
    def __init__(self, downloader=None, actions=None, when=None):
        """
        Initialize metadata parser post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - actions: list[tuple], parsing actions
        - when: str|None, when to run processor
        """
    
    @staticmethod
    def validate_action(*action):
        """
        Validate action specification.
        
        Parameters:
        - *action: action components
        
        Raises:
        ValueError: if action is invalid
        """

Specialized Processing

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

class SponsorBlockPP:
    """
    SponsorBlock integration for marking/removing sponsored segments.
    
    Integrates with SponsorBlock API to identify and handle
    sponsored content, intros, outros, and other segments.
    """
    
    def __init__(self, downloader=None, categories=None, api=None, when=None):
        """
        Initialize SponsorBlock post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - categories: set|None, segment categories to process
        - api: str|None, SponsorBlock API URL
        - when: str|None, when to run processor
        """

class ModifyChaptersPP:
    """
    Modify chapter information in media files.
    
    Adds, removes, or modifies chapters based on patterns,
    SponsorBlock data, or custom specifications.
    """
    
    def __init__(self, downloader=None, remove_chapters_patterns=None, remove_sponsor_segments=None, remove_ranges=None, sponsorblock_chapter_title=None, force_keyframes=False):
        """
        Initialize chapter modification post-processor.
        
        Parameters:
        - downloader: YoutubeDL instance
        - remove_chapters_patterns: list|None, patterns for chapters to remove
        - remove_sponsor_segments: set|None, sponsor segment types to remove
        - remove_ranges: list|None, time ranges to remove
        - sponsorblock_chapter_title: str|None, title template for SponsorBlock chapters
        - force_keyframes: bool, force keyframes at cuts
        """

class XAttrMetadataPP:
    """
    Store metadata in file extended attributes (xattrs).
    
    Saves metadata information in filesystem extended attributes
    for preservation across file operations.
    """
    
    def __init__(self, downloader=None):
        """Initialize extended attributes post-processor."""

class MoveFilesAfterDownloadPP:
    """
    Move files to different locations after processing.
    
    Handles file relocation based on templates and patterns,
    useful for organizing downloads into directory structures.
    """
    
    def __init__(self, downloader=None):
        """Initialize file moving post-processor."""

Post-Processor Management

Functions for discovering and managing post-processors.

def get_postprocessor(key):
    """
    Get post-processor class by key name.
    
    Parameters:
    - key: str, post-processor identifier
    
    Returns:
    type: post-processor class
    
    Raises:
    KeyError: if post-processor not found
    """

Usage Examples

Audio Extraction

import yt_dlp

# Extract MP3 audio at high quality
ydl_opts = {
    'format': 'bestaudio/best',
    'postprocessors': [{
        'key': 'FFmpegExtractAudio',
        'preferredcodec': 'mp3',
        'preferredquality': '192',
    }],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

Video Format Conversion

import yt_dlp

# Convert to MP4 with specific quality
ydl_opts = {
    'format': 'best[height<=720]',
    'postprocessors': [{
        'key': 'FFmpegVideoConvertor',
        'preferedformat': 'mp4',
    }],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

Metadata Embedding

import yt_dlp

# Embed metadata and thumbnail
ydl_opts = {
    'writethumbnail': True,
    'postprocessors': [
        {
            'key': 'FFmpegMetadata',
            'add_metadata': True,
            'add_chapters': True,
        },
        {
            'key': 'EmbedThumbnail',
            'already_have_thumbnail': False,
        },
    ],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

Subtitle Processing

import yt_dlp

# Download and convert subtitles to SRT
ydl_opts = {
    'writesubtitles': True,
    'writeautomaticsub': True,
    'subtitleslangs': ['en', 'es'],
    'postprocessors': [{
        'key': 'FFmpegSubtitlesConvertor',
        'format': 'srt',
    }],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

Custom Processing Pipeline

import yt_dlp

# Complex processing pipeline
ydl_opts = {
    'format': 'best',
    'writethumbnail': True,
    'writesubtitles': True,
    'postprocessors': [
        # First: Convert subtitles
        {
            'key': 'FFmpegSubtitlesConvertor',
            'format': 'srt',
        },
        # Second: Extract audio
        {
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        },
        # Third: Embed metadata
        {
            'key': 'FFmpegMetadata',
            'add_metadata': True,
        },
        # Fourth: Embed thumbnail
        {
            'key': 'EmbedThumbnail',
        },
        # Fifth: Store in extended attributes
        {
            'key': 'XAttrMetadata',
        },
    ],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

SponsorBlock Integration

import yt_dlp

# Remove sponsored segments using SponsorBlock
ydl_opts = {
    'postprocessors': [{
        'key': 'SponsorBlock',
        'categories': ['sponsor', 'intro', 'outro'],
        'api': 'https://sponsor.ajay.app',
        'when': 'after_filter',
    }],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download(['https://www.youtube.com/watch?v=example'])

Custom Post-Processor

import yt_dlp
from yt_dlp.postprocessor import PostProcessor

class CustomPP(PostProcessor):
    def __init__(self, downloader=None):
        super().__init__(downloader)
    
    def run(self, info):
        # Custom processing logic
        filename = info['filepath']
        self.to_screen(f'Custom processing: {filename}')
        
        # Return updated info and files to delete
        return [], info

# Use custom post-processor
ydl_opts = {
    'postprocessors': [{'key': 'Custom'}],
}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    # Register custom post-processor
    ydl.add_post_processor(CustomPP())
    ydl.download(['https://www.youtube.com/watch?v=example'])

Types

# Base post-processor class
class PostProcessor:
    def __init__(self, downloader=None): ...
    def run(self, info): ...
    def to_screen(self, message, skip_eol=False): ...

# Post-processor configuration dictionary
PostProcessorDict = dict[str, Any]

# Processing phases when post-processors can run
POSTPROCESS_WHEN = [
    'pre_process',      # Before extraction
    'after_filter',     # After filtering but before download  
    'before_dl',        # Before download
    'post_process',     # After download (default)
    'after_move',       # After moving files
    'after_video',      # After video processing
    'playlist',         # After playlist processing
]

Install with Tessl CLI

npx tessl i tessl/pypi-yt-dlp

docs

configuration.md

core-download.md

exceptions.md

extractor-system.md

index.md

post-processing.md

utilities.md

tile.json