filmon.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from ..utils import qualities
  5. from ..compat import compat_urllib_request
  6. _QUALITY = qualities(('low', 'high'))
  7. class FilmOnIE(InfoExtractor):
  8. _VALID_URL = r'https?://(?:www\.)?filmon\.com/(?:tv|channel)/(?P<id>[a-z0-9-]+)'
  9. _TESTS = [{
  10. 'url': 'https://www.filmon.com/channel/filmon-sports',
  11. 'only_matching': True,
  12. }, {
  13. 'url': 'https://www.filmon.com/tv/2894',
  14. 'only_matching': True,
  15. }]
  16. def _real_extract(self, url):
  17. channel_id = self._match_id(url)
  18. request = compat_urllib_request.Request('https://www.filmon.com/channel/%s' % (channel_id))
  19. request.add_header('X-Requested-With', 'XMLHttpRequest')
  20. channel_info = self._download_json(request, channel_id)
  21. now_playing = channel_info['now_playing']
  22. thumbnails = []
  23. for thumb in now_playing.get('images', ()):
  24. if thumb['type'] != '2':
  25. continue
  26. thumbnails.append({
  27. 'url': thumb['url'],
  28. 'width': int(thumb['width']),
  29. 'height': int(thumb['height']),
  30. })
  31. formats = []
  32. for stream in channel_info['streams']:
  33. formats.append({
  34. 'format_id': str(stream['id']),
  35. # this is an m3u8 stream, but we are deliberately not using _extract_m3u8_formats
  36. # because 0) it doesn't have bitrate variants anyway, and 1) the ids generated
  37. # by that method are highly unstable (because the bitrate is variable)
  38. 'url': stream['url'],
  39. 'resolution': stream['name'],
  40. 'format_note': 'expires after %u seconds' % int(stream['watch-timeout']),
  41. 'ext': 'mp4',
  42. 'quality': _QUALITY(stream['quality']),
  43. 'preference': int(stream['watch-timeout']),
  44. })
  45. self._sort_formats(formats)
  46. return {
  47. 'id': str(channel_info['id']),
  48. 'display_id': channel_info['alias'],
  49. 'formats': formats,
  50. # XXX: use the channel description (channel_info['description'])?
  51. 'uploader_id': channel_info['alias'],
  52. 'uploader': channel_info['title'], # XXX: kinda stretching it...
  53. 'title': now_playing.get('programme_name') or channel_info['title'],
  54. 'description': now_playing.get('programme_description'),
  55. 'thumbnails': thumbnails,
  56. 'is_live': True,
  57. }
  58. class FilmOnVODIE(InfoExtractor):
  59. _VALID_URL = r'https?://(?:www\.)?filmon\.com/vod/view/(?P<id>\d+)'
  60. _TESTS = [{
  61. 'url': 'https://www.filmon.com/vod/view/24869-0-plan-9-from-outer-space',
  62. 'info_dict': {
  63. 'id': '24869',
  64. 'ext': 'mp4',
  65. 'title': 'Plan 9 From Outer Space',
  66. 'description': 'Dead human, zombies and vampires',
  67. },
  68. }, {
  69. 'url': 'https://www.filmon.com/vod/view/2825-1-popeye-series-1',
  70. 'info_dict': {
  71. 'id': '2825',
  72. 'title': 'Popeye Series 1',
  73. },
  74. 'playlist_count': 8,
  75. }]
  76. def _real_extract(self, url):
  77. video_id = self._match_id(url)
  78. result = self._download_json('https://www.filmon.com/api/vod/movie?id=%s' % (video_id), video_id)
  79. if result['code'] != 200:
  80. raise ExtractorError('FilmOn said: %s' % (result['reason']), expected=True)
  81. response = result['response']
  82. if response.get('episodes'):
  83. return {
  84. '_type': 'playlist',
  85. 'id': video_id,
  86. 'title': response['title'],
  87. 'entries': [{
  88. '_type': 'url',
  89. 'url': 'https://www.filmon.com/vod/view/%s' % (ep),
  90. } for ep in response['episodes']]
  91. }
  92. formats = []
  93. for (id, stream) in response['streams'].items():
  94. formats.append({
  95. 'format_id': id,
  96. 'url': stream['url'],
  97. 'resolution': stream['name'],
  98. 'format_note': 'expires after %u seconds' % int(stream['watch-timeout']),
  99. 'ext': 'mp4',
  100. 'quality': _QUALITY(stream['quality']),
  101. 'preference': int(stream['watch-timeout']),
  102. })
  103. self._sort_formats(formats)
  104. poster = response['poster']
  105. thumbnails = [{
  106. 'id': 'poster',
  107. 'url': poster['url'],
  108. 'width': poster['width'],
  109. 'height': poster['height'],
  110. }]
  111. for (id, thumb) in poster['thumbs'].items():
  112. thumbnails.append({
  113. 'id': id,
  114. 'url': thumb['url'],
  115. 'width': thumb['width'],
  116. 'height': thumb['height'],
  117. })
  118. return {
  119. 'id': video_id,
  120. 'title': response['title'],
  121. 'formats': formats,
  122. 'description': response['description'],
  123. 'thumbnails': thumbnails,
  124. }