From 7c889a211a6aec81f8dd49a0317767cff5753191 Mon Sep 17 00:00:00 2001 From: Renee Margaret McConahy Date: Sat, 26 Dec 2015 10:28:22 -0500 Subject: [PATCH] Change format sorting for YouTube only. --- youtube_dl/extractor/common.py | 4 +-- youtube_dl/extractor/youtube.py | 63 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index ad2020dee..828f58f12 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -811,11 +811,11 @@ class InfoExtractor(object): 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('height') if f.get('height') is not None else -1, - f.get('width') if f.get('width') 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, ext_preference, f.get('abr') if f.get('abr') is not None else -1, audio_ext_preference, diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 4aac2cc03..f99ba6ff6 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -769,6 +769,69 @@ class YoutubeIE(YoutubeBaseInfoExtractor): """Indicate the download will use the RTMP protocol.""" self.to_screen('RTMP download detected') + def _sort_formats(self, formats, field_preference=None): + if not formats: + raise ExtractorError('No video formats found') + + def _formats_key(f): + # TODO remove the following workaround + from ..utils import determine_ext + 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 -1 for field in field_preference) + + preference = f.get('preference') + if preference is None: + proto = f.get('protocol') + if proto is None: + proto = compat_urllib_parse_urlparse(f.get('url', '')).scheme + + preference = 0 if proto in ['http', 'https'] else -0.1 + if f.get('ext') in ['f4f', 'f4m']: # Not yet supported + preference -= 0.5 + + if f.get('vcodec') == 'none': # audio only + if self._downloader.params.get('prefer_free_formats'): + ORDER = ['aac', 'mp3', 'm4a', 'webm', 'ogg', 'opus'] + else: + ORDER = ['webm', 'opus', 'ogg', 'mp3', 'aac', 'm4a'] + ext_preference = 0 + try: + audio_ext_preference = ORDER.index(f['ext']) + except ValueError: + audio_ext_preference = -1 + else: + if self._downloader.params.get('prefer_free_formats'): + ORDER = ['flv', 'mp4', 'webm'] + else: + ORDER = ['webm', 'flv', 'mp4'] + try: + ext_preference = ORDER.index(f['ext']) + except ValueError: + 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('height') if f.get('height') is not None else -1, + f.get('width') if f.get('width') 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, + 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 '', + ) + formats.sort(key=_formats_key) + def _signature_cache_id(self, example_sig): """ Return a string representation of a signature """ return '.'.join(compat_str(len(part)) for part in example_sig.split('.'))