From 0b7c7771d6bb512aaeb8f3f0451e2f124044832c Mon Sep 17 00:00:00 2001 From: pukkandan Date: Mon, 21 Sep 2020 15:43:50 +0530 Subject: [PATCH] add option --format-sort --- youtube_dl/__init__.py | 1 + youtube_dl/extractor/common.py | 51 +++++++++++++++++----------------- youtube_dl/options.py | 8 ++++++ 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index 9a659fc65..e58b169fc 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -338,6 +338,7 @@ def _real_main(argv=None): 'simulate': opts.simulate or any_getting, 'skip_download': opts.skip_download, 'format': opts.format, + 'format_sort': opts.format_sort, 'listformats': opts.listformats, 'outtmpl': outtmpl, 'autonumber_size': opts.autonumber_size, diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 021945a89..33122c431 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -1358,6 +1358,20 @@ class InfoExtractor(object): if not formats: raise ExtractorError('No video formats found') + sort = self._downloader.params.get('format_sort', '') + sort = sort.split(',') if isinstance(sort, str) else [] + if isinstance(field_preference, (list, tuple)): + sort += [f for f in field_preference if f not in sort] + sort += [f for f in + ['preference', 'language_preference', 'quality', 'tbr', # default order + 'filesize', 'vbr', 'height', 'width', + 'proto_preference', 'ext_preference', + 'abr', 'audio_ext_preference', 'fps', + 'filesize_approx', 'source_preference', 'format_id'] + if f not in sort] + if self._downloader.params.get('verbose', False): + self._downloader.to_screen('[debug] Formats sorted by: %s' % sort) + for f in formats: # Automatically determine tbr when missing based on abr and vbr (improves # formats sorting in some cases) @@ -1370,13 +1384,6 @@ class InfoExtractor(object): if not f.get('ext') and 'url' in f: f['ext'] = determine_ext(f['url']) - if isinstance(field_preference, (list, tuple)): - return tuple( - f.get(field) - if f.get(field) is not None - else ('' if field == 'format_id' else -1) - for field in field_preference) - preference = f.get('preference') if preference is None: preference = 0 @@ -1410,24 +1417,18 @@ class InfoExtractor(object): ext_preference = -1 audio_ext_preference = 0 - return ( - preference, - f.get('language_preference') if f.get('language_preference') is not None else -1, - f.get('quality') if f.get('quality') is not None else -1, - f.get('tbr') if f.get('tbr') is not None else -1, - f.get('filesize') if f.get('filesize') is not None else -1, - f.get('vbr') if f.get('vbr') is not None else -1, - f.get('height') if f.get('height') is not None else -1, - f.get('width') if f.get('width') is not None else -1, - proto_preference, - ext_preference, - f.get('abr') if f.get('abr') is not None else -1, - audio_ext_preference, - f.get('fps') if f.get('fps') is not None else -1, - f.get('filesize_approx') if f.get('filesize_approx') is not None else -1, - f.get('source_preference') if f.get('source_preference') is not None else -1, - f.get('format_id') if f.get('format_id') is not None else '', - ) + prefVars = {'preference': preference, + 'proto_preference': proto_preference, + 'ext_preference': ext_preference, + 'audio_ext_preference': audio_ext_preference} + + return tuple( + prefVars.get(field) + if prefVars.get(field) is not None + else (f.get(field) if f.get(field) is not None + else ('' if field == 'format_id' else -1)) + for field in sort) + formats.sort(key=_formats_key) def _check_formats(self, formats, video_id): diff --git a/youtube_dl/options.py b/youtube_dl/options.py index 6d5ac62b3..616194d23 100644 --- a/youtube_dl/options.py +++ b/youtube_dl/options.py @@ -394,6 +394,14 @@ def parseOpts(overrideArguments=None): '-f', '--format', action='store', dest='format', metavar='FORMAT', default=None, help='Video format code, see the "FORMAT SELECTION" for all the info') + video_format.add_option( + '--format-sort', + action='store', dest='format_sort', metavar='FORMAT', default=None, + help=( + 'Specify the fields used to sort the formats (e.g. height,width,tbr). ' + 'Available fields: language_preference, quality, height, width, fps, ' + 'filesize, filesize_approx, tbr, vbr, abr, format_id, ' + 'proto_preference, ext_preference, audio_ext_preference, source_preference')) video_format.add_option( '--all-formats', action='store_const', dest='format', const='all',