hidive.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..compat import compat_str
  6. from ..utils import (
  7. ExtractorError,
  8. int_or_none,
  9. urlencode_postdata,
  10. )
  11. class HiDiveIE(InfoExtractor):
  12. _VALID_URL = r'https?://(?:www\.)?hidive\.com/stream/(?P<title>[^/]+)/(?P<key>[^/?#&]+)'
  13. # Using X-Forwarded-For results in 403 HTTP error for HLS fragments,
  14. # so disabling geo bypass completely
  15. _GEO_BYPASS = False
  16. _TESTS = [{
  17. 'url': 'https://www.hidive.com/stream/the-comic-artist-and-his-assistants/s01e001',
  18. 'info_dict': {
  19. 'id': 'the-comic-artist-and-his-assistants/s01e001',
  20. 'ext': 'mp4',
  21. 'title': 'the-comic-artist-and-his-assistants/s01e001',
  22. 'series': 'the-comic-artist-and-his-assistants',
  23. 'season_number': 1,
  24. 'episode_number': 1,
  25. },
  26. 'params': {
  27. 'skip_download': True,
  28. 'proxy': '192.99.245.228:3128',
  29. },
  30. }]
  31. def _real_extract(self, url):
  32. mobj = re.match(self._VALID_URL, url)
  33. title, key = mobj.group('title', 'key')
  34. video_id = '%s/%s' % (title, key)
  35. settings = self._download_json(
  36. 'https://www.hidive.com/play/settings', video_id,
  37. data=urlencode_postdata({
  38. 'Title': title,
  39. 'Key': key,
  40. }))
  41. restriction = settings.get('restrictionReason')
  42. if restriction == 'RegionRestricted':
  43. self.raise_geo_restricted()
  44. if restriction and restriction != 'None':
  45. raise ExtractorError(
  46. '%s said: %s' % (self.IE_NAME, restriction), expected=True)
  47. formats = []
  48. subtitles = {}
  49. for rendition_id, rendition in settings['renditions'].items():
  50. bitrates = rendition.get('bitrates')
  51. if not isinstance(bitrates, dict):
  52. continue
  53. m3u8_url = bitrates.get('hls')
  54. if not isinstance(m3u8_url, compat_str):
  55. continue
  56. formats.extend(self._extract_m3u8_formats(
  57. m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native',
  58. m3u8_id='%s-hls' % rendition_id, fatal=False))
  59. cc_files = rendition.get('ccFiles')
  60. if not isinstance(cc_files, list):
  61. continue
  62. for cc_file in cc_files:
  63. if not isinstance(cc_file, list) or len(cc_file) < 3:
  64. continue
  65. cc_lang = cc_file[0]
  66. cc_url = cc_file[2]
  67. if not isinstance(cc_lang, compat_str) or not isinstance(
  68. cc_url, compat_str):
  69. continue
  70. subtitles.setdefault(cc_lang, []).append({
  71. 'url': cc_url,
  72. })
  73. season_number = int_or_none(self._search_regex(
  74. r's(\d+)', key, 'season number', default=None))
  75. episode_number = int_or_none(self._search_regex(
  76. r'e(\d+)', key, 'episode number', default=None))
  77. return {
  78. 'id': video_id,
  79. 'title': video_id,
  80. 'subtitles': subtitles,
  81. 'formats': formats,
  82. 'series': title,
  83. 'season_number': season_number,
  84. 'episode_number': episode_number,
  85. }