pladform.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. from .common import InfoExtractor
  2. from ..utils import (
  3. ExtractorError,
  4. determine_ext,
  5. int_or_none,
  6. parse_qs,
  7. qualities,
  8. xpath_text,
  9. )
  10. class PladformIE(InfoExtractor):
  11. _VALID_URL = r'''(?x)
  12. https?://
  13. (?:
  14. (?:
  15. out\.pladform\.ru/player|
  16. static\.pladform\.ru/player\.swf
  17. )
  18. \?.*\bvideoid=|
  19. video\.pladform\.ru/catalog/video/videoid/
  20. )
  21. (?P<id>\d+)
  22. '''
  23. _EMBED_REGEX = [r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//out\.pladform\.ru/player\?.+?)\1']
  24. _TESTS = [{
  25. 'url': 'http://out.pladform.ru/player?pl=18079&type=html5&videoid=100231282',
  26. 'info_dict': {
  27. 'id': '6216d548e755edae6e8280667d774791',
  28. 'ext': 'mp4',
  29. 'timestamp': 1406117012,
  30. 'title': 'Гарик Мартиросян и Гарик Харламов - Кастинг на концерт ко Дню милиции',
  31. 'age_limit': 0,
  32. 'upload_date': '20140723',
  33. 'thumbnail': str,
  34. 'view_count': int,
  35. 'description': str,
  36. 'uploader_id': '12082',
  37. 'uploader': 'Comedy Club',
  38. 'duration': 367,
  39. },
  40. 'expected_warnings': ['HTTP Error 404: Not Found'],
  41. }, {
  42. 'url': 'https://out.pladform.ru/player?pl=64471&videoid=3777899&vk_puid15=0&vk_puid34=0',
  43. 'md5': '53362fac3a27352da20fa2803cc5cd6f',
  44. 'info_dict': {
  45. 'id': '3777899',
  46. 'ext': 'mp4',
  47. 'title': 'СТУДИЯ СОЮЗ • Шоу Студия Союз, 24 выпуск (01.02.2018) Нурлан Сабуров и Слава Комиссаренко',
  48. 'description': 'md5:05140e8bf1b7e2d46e7ba140be57fd95',
  49. 'thumbnail': r're:^https?://.*\.jpg$',
  50. 'duration': 3190,
  51. },
  52. }, {
  53. 'url': 'http://static.pladform.ru/player.swf?pl=21469&videoid=100183293&vkcid=0',
  54. 'only_matching': True,
  55. }, {
  56. 'url': 'http://video.pladform.ru/catalog/video/videoid/100183293/vkcid/0',
  57. 'only_matching': True,
  58. }]
  59. def _real_extract(self, url):
  60. video_id = self._match_id(url)
  61. qs = parse_qs(url)
  62. pl = qs.get('pl', ['1'])[0]
  63. video = self._download_xml(
  64. 'http://out.pladform.ru/getVideo', video_id, query={
  65. 'pl': pl,
  66. 'videoid': video_id,
  67. }, fatal=False)
  68. def fail(text):
  69. raise ExtractorError(
  70. f'{self.IE_NAME} returned error: {text}',
  71. expected=True)
  72. if not video:
  73. target_url = self._request_webpage(url, video_id, note='Resolving final URL').url
  74. if target_url == url:
  75. raise ExtractorError('Can\'t parse page')
  76. return self.url_result(target_url)
  77. if video.tag == 'error':
  78. fail(video.text)
  79. quality = qualities(('ld', 'sd', 'hd'))
  80. formats = []
  81. for src in video.findall('./src'):
  82. if src is None:
  83. continue
  84. format_url = src.text
  85. if not format_url:
  86. continue
  87. if src.get('type') == 'hls' or determine_ext(format_url) == 'm3u8':
  88. formats.extend(self._extract_m3u8_formats(
  89. format_url, video_id, 'mp4', entry_protocol='m3u8_native',
  90. m3u8_id='hls', fatal=False))
  91. else:
  92. formats.append({
  93. 'url': src.text,
  94. 'format_id': src.get('quality'),
  95. 'quality': quality(src.get('quality')),
  96. })
  97. if not formats:
  98. error = xpath_text(video, './cap', 'error', default=None)
  99. if error:
  100. fail(error)
  101. webpage = self._download_webpage(
  102. f'http://video.pladform.ru/catalog/video/videoid/{video_id}',
  103. video_id)
  104. title = self._og_search_title(webpage, fatal=False) or xpath_text(
  105. video, './/title', 'title', fatal=True)
  106. description = self._search_regex(
  107. r'</h3>\s*<p>([^<]+)</p>', webpage, 'description', fatal=False)
  108. thumbnail = self._og_search_thumbnail(webpage) or xpath_text(
  109. video, './/cover', 'cover')
  110. duration = int_or_none(xpath_text(video, './/time', 'duration'))
  111. age_limit = int_or_none(xpath_text(video, './/age18', 'age limit'))
  112. return {
  113. 'id': video_id,
  114. 'title': title,
  115. 'description': description,
  116. 'thumbnail': thumbnail,
  117. 'duration': duration,
  118. 'age_limit': age_limit,
  119. 'formats': formats,
  120. }