### yt-dlp Plugin Installation Structure using setup.cfg Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt Illustrates the necessary configuration for installing yt-dlp plugins using a setup.cfg file. It specifies the package name, version, and uses `find_namespace:` to enable automatic discovery by yt-dlp's namespace package mechanism. ```ini # setup.cfg [metadata] name = yt-dlp-sample-plugins version = 2023.01.01 [options] packages = find_namespace: ``` -------------------------------- ### Implement yt-dlp PostProcessor using Python Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt Demonstrates how to create a PostProcessor for yt-dlp to handle downloaded files. PostProcessors can perform operations like format conversion, metadata embedding, or custom file manipulation after a file has been downloaded. ```python from yt_dlp.postprocessor.common import PostProcessor class SamplePluginPP(PostProcessor): def __init__(self, downloader=None, **kwargs): super().__init__(downloader) self._kwargs = kwargs def run(self, info): filepath = info.get('filepath') if filepath: # Post-download processing self.to_screen(f'Post-processed {filepath!r} with {self._kwargs}') # Example: Access file metadata video_id = info.get('id') title = info.get('title') duration = info.get('duration') self.to_screen(f'Video ID: {video_id}, Title: {title}, Duration: {duration}s') # Example: Perform custom operations # import os # filesize = os.path.getsize(filepath) # self.to_screen(f'File size: {filesize} bytes') else: # Pre-download processing filepath = info.get('_filename') self.to_screen(f'Pre-processed {filepath!r} with {self._kwargs}') # Return: (files_to_delete, modified_info_dict) return [], info # Usage from command line: # yt-dlp --use-postprocessor SamplePlugin:key1=value1:key2=value2 URL # Example: # yt-dlp --use-postprocessor SamplePlugin:format=mp4:quality=high https://example.com/video ``` -------------------------------- ### Implement Custom Postprocessor with Python Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt This snippet demonstrates how to create a custom postprocessor for yt-dlp using Python. It involves defining a class that inherits from PostProcessor and implementing the run method. The postprocessor can be triggered at different stages (pre- or post-processing) and can perform actions like creating metadata files or renaming downloaded files. Dependencies include the yt_dlp.postprocessor.common.PostProcessor class, 'os', and 'json' modules. ```python from yt_dlp.postprocessor.common import PostProcessor import os import json class AdvancedPluginPP(PostProcessor): def __init__(self, downloader=None, **kwargs): super().__init__(downloader) self.output_format = kwargs.get('output', 'json') self.prefix = kwargs.get('prefix', 'processed_') def run(self, info): filepath = info.get('filepath') if not filepath: # Pre-processing stage return [], info # Post-processing stage video_id = info.get('id') title = info.get('title') # Example: Create metadata file metadata_path = filepath + '.meta.json' metadata = { 'id': video_id, 'title': title, 'uploader': info.get('uploader'), 'duration': info.get('duration'), 'upload_date': info.get('upload_date'), 'view_count': info.get('view_count'), 'like_count': info.get('like_count'), } with open(metadata_path, 'w', encoding='utf-8') as f: json.dump(metadata, f, indent=2, ensure_ascii=False) self.to_screen(f'Created metadata file: {metadata_path}') # Example: Rename file with custom prefix directory = os.path.dirname(filepath) filename = os.path.basename(filepath) new_filepath = os.path.join(directory, self.prefix + filename) # Don't actually rename in example, but show how # os.rename(filepath, new_filepath) # info['filepath'] = new_filepath # Return files to delete (none) and modified info return [], info # Usage with timing control: # yt-dlp --use-postprocessor AdvancedPlugin:output=json:prefix=dl_ URL # Usage with when parameter: # yt-dlp --use-postprocessor "AdvancedPlugin:when=pre_process" URL # yt-dlp --use-postprocessor "AdvancedPlugin:when=post_process" URL ``` -------------------------------- ### Implement Custom yt-dlp Extractor using Python Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt Demonstrates how to create a custom extractor for yt-dlp by inheriting from InfoExtractor and implementing the _real_extract method. This allows yt-dlp to download videos from new sources by defining URL patterns and extraction logic. ```python from yt_dlp.extractor.common import InfoExtractor class SamplePluginIE(InfoExtractor): _WORKING = False _VALID_URL = r'^sampleplugin:' def _real_extract(self, url): self.to_screen('URL "%s" successfully captured' % url) # Example: Return video information dictionary return { 'id': 'sample_video_001', 'title': 'Sample Video Title', 'url': 'https://example.com/video.mp4', 'ext': 'mp4', 'description': 'A sample video description', 'uploader': 'Sample Uploader', 'duration': 300, } # Usage from command line: # yt-dlp sampleplugin:some_video_id ``` -------------------------------- ### Create Custom Extractor with Python Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt This snippet shows how to create a custom extractor for yt-dlp. It requires defining a class that inherits from InfoExtractor, setting a valid URL pattern, and implementing the _real_extract method to parse video information from a given URL. Dependencies include the yt_dlp.extractor.common.InfoExtractor class and the 're' module. ```python from yt_dlp.extractor.common import InfoExtractor import re class CustomSiteIE(InfoExtractor): # Required: Class name must end with "IE" _WORKING = True # Set to False during development _VALID_URL = r'https?://(?:www\.)?customsite\.com/watch/(?P[0-9]+)' # Optional: Set test cases _TESTS = [{ 'url': 'https://customsite.com/watch/12345', 'info_dict': { 'id': '12345', 'ext': 'mp4', 'title': 'Test Video', } }] def _real_extract(self, url): # Extract video ID from URL video_id = self._match_id(url) # Example: Fetch webpage webpage = self._download_webpage(url, video_id) # Example: Extract title using regex title = self._html_search_regex( r']+class="title"[^>]*>([^<]+)', webpage, 'video title', default='Unknown') # Example: Extract JSON data video_data = self._search_json( r'var\s+videoData\s*=\s*', webpage, 'video data', video_id, default={}) # Return info dictionary return { 'id': video_id, 'title': title, 'url': video_data.get('video_url'), 'ext': 'mp4', 'thumbnail': video_data.get('thumbnail'), 'description': self._og_search_description(webpage), 'uploader': video_data.get('uploader'), 'view_count': int(video_data.get('views', 0)), 'like_count': int(video_data.get('likes', 0)), } # Usage: # yt-dlp https://customsite.com/watch/12345 ``` -------------------------------- ### Override Existing yt-dlp Extractor using Python Source: https://context7.com/yt-dlp/yt-dlp-sample-plugins/llms.txt Shows how to override existing yt-dlp extractors to modify their behavior, such as adding custom logging or preprocessing. This pattern uses inheritance and the plugin_name parameter to inject custom logic into the extraction pipeline. ```python from yt_dlp.extractor.youtube import YoutubeIE class _SampleOverridePluginIE(YoutubeIE, plugin_name='sample'): def _real_extract(self, url): self.to_screen('Passing through SampleOverridePluginIE') # Add custom pre-processing self.to_screen(f'Processing YouTube URL: {url}') # Call parent extractor result = super()._real_extract(url) # Add custom post-processing to result if result: result['custom_field'] = 'Modified by plugin' self.to_screen(f'Extracted: {result.get("title")}') return result # Usage from command line: # yt-dlp https://www.youtube.com/watch?v=dQw4w9WgXcQ # The override automatically intercepts YouTube URLs ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.