diff options
Diffstat (limited to 'youtube_dl/extractor/fivemin.py')
| -rw-r--r-- | youtube_dl/extractor/fivemin.py | 84 | 
1 files changed, 71 insertions, 13 deletions
| diff --git a/youtube_dl/extractor/fivemin.py b/youtube_dl/extractor/fivemin.py index 157094e8c..2955965d9 100644 --- a/youtube_dl/extractor/fivemin.py +++ b/youtube_dl/extractor/fivemin.py @@ -2,11 +2,15 @@ from __future__ import unicode_literals  from .common import InfoExtractor  from ..compat import ( -    compat_str,      compat_urllib_parse, +    compat_parse_qs, +    compat_urllib_parse_urlparse, +    compat_urlparse,  )  from ..utils import (      ExtractorError, +    parse_duration, +    replace_extension,  ) @@ -28,6 +32,7 @@ class FiveMinIE(InfoExtractor):                  'id': '518013791',                  'ext': 'mp4',                  'title': 'iPad Mini with Retina Display Review', +                'duration': 177,              },          },          { @@ -38,9 +43,52 @@ class FiveMinIE(InfoExtractor):                  'id': '518086247',                  'ext': 'mp4',                  'title': 'How to Make a Next-Level Fruit Salad', +                'duration': 184,              },          },      ] +    _ERRORS = { +        'ErrorVideoNotExist': 'We\'re sorry, but the video you are trying to watch does not exist.', +        'ErrorVideoNoLongerAvailable': 'We\'re sorry, but the video you are trying to watch is no longer available.', +        'ErrorVideoRejected': 'We\'re sorry, but the video you are trying to watch has been removed.', +        'ErrorVideoUserNotGeo': 'We\'re sorry, but the video you are trying to watch cannot be viewed from your current location.', +        'ErrorVideoLibraryRestriction': 'We\'re sorry, but the video you are trying to watch is currently unavailable for viewing at this domain.', +        'ErrorExposurePermission': 'We\'re sorry, but the video you are trying to watch is currently unavailable for viewing at this domain.', +    } +    _QUALITIES = { +        1: { +            'width': 640, +            'height': 360, +        }, +        2: { +            'width': 854, +            'height': 480, +        }, +        4: { +            'width': 1280, +            'height': 720, +        }, +        8: { +            'width': 1920, +            'height': 1080, +        }, +        16: { +            'width': 640, +            'height': 360, +        }, +        32: { +            'width': 854, +            'height': 480, +        }, +        64: { +            'width': 1280, +            'height': 720, +        }, +        128: { +            'width': 640, +            'height': 360, +        }, +    }      def _real_extract(self, url):          video_id = self._match_id(url) @@ -59,26 +107,36 @@ class FiveMinIE(InfoExtractor):              'https://syn.5min.com/handlers/SenseHandler.ashx?' + query,              video_id)          if not response['success']: -            err_msg = response['errorMessage'] -            if err_msg == 'ErrorVideoUserNotGeo': -                msg = 'Video not available from your location' -            else: -                msg = 'Aol said: %s' % err_msg -            raise ExtractorError(msg, expected=True, video_id=video_id) +            raise ExtractorError( +                '%s said: %s' % ( +                    self.IE_NAME, +                    self._ERRORS.get(response['errorMessage'], response['errorMessage'])), +                expected=True)          info = response['binding'][0] -        second_id = compat_str(int(video_id[:-2]) + 1)          formats = [] -        for quality, height in [(1, 320), (2, 480), (4, 720), (8, 1080)]: -            if any(r['ID'] == quality for r in info['Renditions']): +        parsed_video_url = compat_urllib_parse_urlparse(compat_parse_qs( +            compat_urllib_parse_urlparse(info['EmbededURL']).query)['videoUrl'][0]) +        for rendition in info['Renditions']: +            if rendition['RenditionType'] == 'm3u8': +                formats.extend(self._extract_m3u8_formats(rendition['Url'], video_id, m3u8_id='hls')) +            elif rendition['RenditionType'] == 'aac': +                continue +            else: +                rendition_url = compat_urlparse.urlunparse(parsed_video_url._replace(path=replace_extension(parsed_video_url.path.replace('//', '/%s/' % rendition['ID']), rendition['RenditionType']))) +                quality = self._QUALITIES.get(rendition['ID'], {})                  formats.append({ -                    'format_id': compat_str(quality), -                    'url': 'http://avideos.5min.com/%s/%s/%s_%s.mp4' % (second_id[-3:], second_id, video_id, quality), -                    'height': height, +                    'format_id': '%s-%d' % (rendition['RenditionType'], rendition['ID']), +                    'url': rendition_url, +                    'width': quality.get('width'), +                    'height': quality.get('height'),                  }) +        self._sort_formats(formats)          return {              'id': video_id,              'title': info['Title'], +            'thumbnail': info.get('ThumbURL'), +            'duration': parse_duration(info.get('Duration')),              'formats': formats,          } | 
