diff options
| -rw-r--r-- | youtube_dl/extractor/extractors.py | 1 | ||||
| -rw-r--r-- | youtube_dl/extractor/filmon.py | 144 | 
2 files changed, 145 insertions, 0 deletions
diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 578359a5e..c9b9ebd23 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -287,6 +287,7 @@ from .fc2 import (      FC2EmbedIE,  )  from .fczenit import FczenitIE +from .filmon import FilmOnIE, FilmOnVODIE  from .firstpost import FirstpostIE  from .firsttv import FirstTVIE  from .fivemin import FiveMinIE diff --git a/youtube_dl/extractor/filmon.py b/youtube_dl/extractor/filmon.py new file mode 100644 index 000000000..987792fec --- /dev/null +++ b/youtube_dl/extractor/filmon.py @@ -0,0 +1,144 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor +from ..utils import qualities +from ..compat import compat_urllib_request + + +_QUALITY = qualities(('low', 'high')) + + +class FilmOnIE(InfoExtractor): +    _VALID_URL = r'https?://(?:www\.)?filmon\.com/(?:tv|channel)/(?P<id>[a-z0-9-]+)' +    _TESTS = [{ +        'url': 'https://www.filmon.com/channel/filmon-sports', +        'only_matching': True, +    }, { +        'url': 'https://www.filmon.com/tv/2894', +        'only_matching': True, +    }] + +    def _real_extract(self, url): +        channel_id = self._match_id(url) + +        request = compat_urllib_request.Request('https://www.filmon.com/channel/%s' % (channel_id)) +        request.add_header('X-Requested-With', 'XMLHttpRequest') +        channel_info = self._download_json(request, channel_id) +        now_playing = channel_info['now_playing'] + +        thumbnails = [] +        for thumb in now_playing.get('images', ()): +            if thumb['type'] != '2': +                continue +            thumbnails.append({ +                'url': thumb['url'], +                'width': int(thumb['width']), +                'height': int(thumb['height']), +            }) + +        formats = [] + +        for stream in channel_info['streams']: +            formats.append({ +                'format_id': str(stream['id']), +                # this is an m3u8 stream, but we are deliberately not using _extract_m3u8_formats +                # because 0) it doesn't have bitrate variants anyway, and 1) the ids generated +                # by that method are highly unstable (because the bitrate is variable) +                'url': stream['url'], +                'resolution': stream['name'], +                'format_note': 'expires after %u seconds' % int(stream['watch-timeout']), +                'ext': 'mp4', +                'quality': _QUALITY(stream['quality']), +                'preference': int(stream['watch-timeout']), +            }) +        self._sort_formats(formats) + +        return { +            'id': str(channel_info['id']), +            'display_id': channel_info['alias'], +            'formats': formats, +            # XXX: use the channel description (channel_info['description'])? +            'uploader_id': channel_info['alias'], +            'uploader': channel_info['title'], # XXX: kinda stretching it... +            'title': now_playing.get('programme_name') or channel_info['title'], +            'description': now_playing.get('programme_description'), +            'thumbnails': thumbnails, +            'is_live': True, +        } + + +class FilmOnVODIE(InfoExtractor): +    _VALID_URL = r'https?://(?:www\.)?filmon\.com/vod/view/(?P<id>\d+)' +    _TESTS = [{ +        'url': 'https://www.filmon.com/vod/view/24869-0-plan-9-from-outer-space', +        'info_dict': { +            'id': '24869', +            'ext': 'mp4', +            'title': 'Plan 9 From Outer Space', +            'description': 'Dead human, zombies and vampires', +        }, +    }, { +        'url': 'https://www.filmon.com/vod/view/2825-1-popeye-series-1', +        'info_dict': { +            'id': '2825', +            'title': 'Popeye Series 1', +        }, +        'playlist_count': 8, +    }] + +    def _real_extract(self, url): +        video_id = self._match_id(url) + +        result = self._download_json('https://www.filmon.com/api/vod/movie?id=%s' % (video_id), video_id) +        if result['code'] != 200: +            raise ExtractorError('FilmOn said: %s' % (result['reason']), expected=True) + +        response = result['response'] + +        if response.get('episodes'): +            return { +                '_type': 'playlist', +                'id': video_id, +                'title': response['title'], +                'entries': [{ +                    '_type': 'url', +                    'url': 'https://www.filmon.com/vod/view/%s' % (ep), +                } for ep in response['episodes']] +            } + +        formats = [] +        for (id, stream) in response['streams'].items(): +            formats.append({ +                'format_id': id, +                'url': stream['url'], +                'resolution': stream['name'], +                'format_note': 'expires after %u seconds' % int(stream['watch-timeout']), +                'ext': 'mp4', +                'quality': _QUALITY(stream['quality']), +                'preference': int(stream['watch-timeout']), +            }) +        self._sort_formats(formats) + +        poster = response['poster'] +        thumbnails = [{ +            'id': 'poster', +            'url': poster['url'], +            'width': poster['width'], +            'height': poster['height'], +        }] +        for (id, thumb) in poster['thumbs'].items(): +            thumbnails.append({ +                'id': id, +                'url': thumb['url'], +                'width': thumb['width'], +                'height': thumb['height'], +            }) + +        return { +            'id': video_id, +            'title': response['title'], +            'formats': formats, +            'description': response['description'], +            'thumbnails': thumbnails, +        }  | 
