You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.2 KiB

  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. },
  29. }]
  30. def _real_extract(self, url):
  31. mobj = re.match(self._VALID_URL, url)
  32. title, key = mobj.group('title', 'key')
  33. video_id = '%s/%s' % (title, key)
  34. settings = self._download_json(
  35. 'https://www.hidive.com/play/settings', video_id,
  36. data=urlencode_postdata({
  37. 'Title': title,
  38. 'Key': key,
  39. }))
  40. restriction = settings.get('restrictionReason')
  41. if restriction == 'RegionRestricted':
  42. self.raise_geo_restricted()
  43. if restriction and restriction != 'None':
  44. raise ExtractorError(
  45. '%s said: %s' % (self.IE_NAME, restriction), expected=True)
  46. formats = []
  47. subtitles = {}
  48. for rendition_id, rendition in settings['renditions'].items():
  49. bitrates = rendition.get('bitrates')
  50. if not isinstance(bitrates, dict):
  51. continue
  52. m3u8_url = bitrates.get('hls')
  53. if not isinstance(m3u8_url, compat_str):
  54. continue
  55. formats.extend(self._extract_m3u8_formats(
  56. m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native',
  57. m3u8_id='%s-hls' % rendition_id, fatal=False))
  58. cc_files = rendition.get('ccFiles')
  59. if not isinstance(cc_files, list):
  60. continue
  61. for cc_file in cc_files:
  62. if not isinstance(cc_file, list) or len(cc_file) < 3:
  63. continue
  64. cc_lang = cc_file[0]
  65. cc_url = cc_file[2]
  66. if not isinstance(cc_lang, compat_str) or not isinstance(
  67. cc_url, compat_str):
  68. continue
  69. subtitles.setdefault(cc_lang, []).append({
  70. 'url': cc_url,
  71. })
  72. season_number = int_or_none(self._search_regex(
  73. r's(\d+)', key, 'season number', default=None))
  74. episode_number = int_or_none(self._search_regex(
  75. r'e(\d+)', key, 'episode number', default=None))
  76. return {
  77. 'id': video_id,
  78. 'title': video_id,
  79. 'subtitles': subtitles,
  80. 'formats': formats,
  81. 'series': title,
  82. 'season_number': season_number,
  83. 'episode_number': episode_number,
  84. }