From 784320c98c2a7e84d72636bc25f6f54c86f5e481 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Thu, 17 Nov 2022 10:53:05 +0530 Subject: [PATCH] Implement universal format sorting Closes #5566 --- yt_dlp/YoutubeDL.py | 14 ++++++++++++++ yt_dlp/extractor/common.py | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 25c35dc53..b1d009280 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -67,6 +67,7 @@ EntryNotInPlaylist, ExistingVideoReached, ExtractorError, + FormatSorter, GeoRestrictedError, HEADRequest, ISO3166Utils, @@ -2461,6 +2462,18 @@ def _raise_pending_errors(self, info): if err: self.report_error(err, tb=False) + def sort_formats(self, info_dict): + formats = self._get_formats(info_dict) + if not formats: + return + # Backward compatibility with InfoExtractor._sort_formats + field_preference = formats[0].pop('__sort_fields', None) + if field_preference: + info_dict['_format_sort_fields'] = field_preference + + formats.sort(key=FormatSorter( + self, info_dict.get('_format_sort_fields', [])).calculate_preference) + def process_video_result(self, info_dict, download=True): assert info_dict.get('_type', 'video') == 'video' self._num_videos += 1 @@ -2546,6 +2559,7 @@ def sanitize_numeric_fields(info): info_dict['requested_subtitles'] = self.process_subtitles( info_dict['id'], subtitles, automatic_captions) + self.sort_formats(info_dict) formats = self._get_formats(info_dict) # or None ensures --clean-infojson removes it diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index e71016c3a..3701fe6b3 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -344,6 +344,7 @@ class InfoExtractor: 'unlisted' or 'public'. Use 'InfoExtractor._availability' to set it _old_archive_ids: A list of old archive ids needed for backward compatibility + _format_sort_fields: A list of fields to use for sorting formats __post_extractor: A function to be called just before the metadata is written to either disk, logger or console. The function must return a dict which will be added to the info_dict. @@ -1698,9 +1699,8 @@ def __init__(ie, *args, **kwargs): return FormatSort def _sort_formats(self, formats, field_preference=[]): - if not formats: - return - formats.sort(key=FormatSorter(self._downloader, field_preference).calculate_preference) + if formats and field_preference: + formats[0]['__sort_fields'] = field_preference def _check_formats(self, formats, video_id): if formats: