diff options
| -rw-r--r-- | youtube_dl/YoutubeDL.py | 13 | ||||
| -rw-r--r-- | youtube_dl/extractor/common.py | 41 | ||||
| -rw-r--r-- | youtube_dl/extractor/youtube.py | 11 | 
3 files changed, 44 insertions, 21 deletions
| diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index d0cb52a51..4910a2912 100644 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -676,17 +676,8 @@ class YoutubeDL(object):              formats = list(takewhile_inclusive(                  lambda f: f['format_id'] != format_limit, formats              )) -        if self.params.get('prefer_free_formats'): -            def _free_formats_key(f): -                try: -                    ext_ord = [u'flv', u'mp4', u'webm'].index(f['ext']) -                except ValueError: -                    ext_ord = -1 -                # We only compare the extension if they have the same height and width -                return (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_ord) -            formats = sorted(formats, key=_free_formats_key) + +        # TODO Central sorting goes here          if formats[0] is not info_dict:               # only set the 'formats' fields if the original info_dict list them diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 123af43c6..280693d1d 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -436,6 +436,47 @@ class InfoExtractor(object):          }          return RATING_TABLE.get(rating.lower(), None) +    def _sort_formats(self, formats): +        def _formats_key(f): +            preference = f.get('preference') +            if preference is None: +                preference = 0 if f.get('url', '').startswith('http') 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 = [u'aac', u'mp3', u'm4a', u'webm', u'ogg', u'opus'] +                else: +                    ORDER = [u'webm', u'opus', u'ogg', u'mp3', u'aac', u'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 = [u'flv', u'mp4', u'webm'] +                else: +                    ORDER = [u'webm', u'flv', u'mp4'] +                try: +                    ext_preference = ORDER.index(f['ext']) +                except ValueError: +                    ext_preference = -1 +                audio_ext_preference = 0 + +            return ( +                preference, +                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('vbr') if f.get('vbr') is not None else -1, +                f.get('abr') if f.get('abr') is not None else -1, +                audio_ext_preference, +                f.get('filesize') if f.get('filesize') is not None else -1, +                f.get('format_id'), +            ) +        formats.sort(key=_formats_key)  class SearchInfoExtractor(InfoExtractor): diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 55c345e8a..829d84e9b 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -1433,16 +1433,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor):                  'format_note': note,              }) -        def _formats_key(f): -            note = f.get('format_note') -            if note is None: -                note = u'' -            is_dash = u'DASH' in note -            return ( -                0 if is_dash 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) -        formats.sort(key=_formats_key) +        self._sort_formats(formats)          return {              'id':           video_id, | 
