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.

134 lines
4.7 KiB

  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..compat import (
  6. compat_str,
  7. compat_urlparse,
  8. )
  9. from ..utils import (
  10. ExtractorError,
  11. float_or_none,
  12. parse_duration,
  13. str_to_int,
  14. urlencode_postdata,
  15. )
  16. class PandoraTVIE(InfoExtractor):
  17. IE_NAME = 'pandora.tv'
  18. IE_DESC = '판도라TV'
  19. _VALID_URL = r'''(?x)
  20. https?://
  21. (?:
  22. (?:www\.)?pandora\.tv/view/(?P<user_id>[^/]+)/(?P<id>\d+)| # new format
  23. (?:.+?\.)?channel\.pandora\.tv/channel/video\.ptv\?| # old format
  24. m\.pandora\.tv/?\? # mobile
  25. )
  26. '''
  27. _TESTS = [{
  28. 'url': 'http://jp.channel.pandora.tv/channel/video.ptv?c1=&prgid=53294230&ch_userid=mikakim&ref=main&lot=cate_01_2',
  29. 'info_dict': {
  30. 'id': '53294230',
  31. 'ext': 'flv',
  32. 'title': '頭を撫でてくれる?',
  33. 'description': '頭を撫でてくれる?',
  34. 'thumbnail': r're:^https?://.*\.jpg$',
  35. 'duration': 39,
  36. 'upload_date': '20151218',
  37. 'uploader': 'カワイイ動物まとめ',
  38. 'uploader_id': 'mikakim',
  39. 'view_count': int,
  40. 'like_count': int,
  41. }
  42. }, {
  43. 'url': 'http://channel.pandora.tv/channel/video.ptv?ch_userid=gogoucc&prgid=54721744',
  44. 'info_dict': {
  45. 'id': '54721744',
  46. 'ext': 'flv',
  47. 'title': '[HD] JAPAN COUNTDOWN 170423',
  48. 'description': '[HD] JAPAN COUNTDOWN 170423',
  49. 'thumbnail': r're:^https?://.*\.jpg$',
  50. 'duration': 1704.9,
  51. 'upload_date': '20170423',
  52. 'uploader': 'GOGO_UCC',
  53. 'uploader_id': 'gogoucc',
  54. 'view_count': int,
  55. 'like_count': int,
  56. },
  57. 'params': {
  58. # Test metadata only
  59. 'skip_download': True,
  60. },
  61. }, {
  62. 'url': 'http://www.pandora.tv/view/mikakim/53294230#36797454_new',
  63. 'only_matching': True,
  64. }, {
  65. 'url': 'http://m.pandora.tv/?c=view&ch_userid=mikakim&prgid=54600346',
  66. 'only_matching': True,
  67. }]
  68. def _real_extract(self, url):
  69. mobj = re.match(self._VALID_URL, url)
  70. user_id = mobj.group('user_id')
  71. video_id = mobj.group('id')
  72. if not user_id or not video_id:
  73. qs = compat_urlparse.parse_qs(compat_urlparse.urlparse(url).query)
  74. video_id = qs.get('prgid', [None])[0]
  75. user_id = qs.get('ch_userid', [None])[0]
  76. if any(not f for f in (video_id, user_id,)):
  77. raise ExtractorError('Invalid URL', expected=True)
  78. data = self._download_json(
  79. 'http://m.pandora.tv/?c=view&m=viewJsonApi&ch_userid=%s&prgid=%s'
  80. % (user_id, video_id), video_id)
  81. info = data['data']['rows']['vod_play_info']['result']
  82. formats = []
  83. for format_id, format_url in info.items():
  84. if not format_url:
  85. continue
  86. height = self._search_regex(
  87. r'^v(\d+)[Uu]rl$', format_id, 'height', default=None)
  88. if not height:
  89. continue
  90. play_url = self._download_json(
  91. 'http://m.pandora.tv/?c=api&m=play_url', video_id,
  92. data=urlencode_postdata({
  93. 'prgid': video_id,
  94. 'runtime': info.get('runtime'),
  95. 'vod_url': format_url,
  96. }),
  97. headers={
  98. 'Origin': url,
  99. 'Content-Type': 'application/x-www-form-urlencoded',
  100. })
  101. format_url = play_url.get('url')
  102. if not format_url:
  103. continue
  104. formats.append({
  105. 'format_id': '%sp' % height,
  106. 'url': format_url,
  107. 'height': int(height),
  108. })
  109. self._sort_formats(formats)
  110. return {
  111. 'id': video_id,
  112. 'title': info['subject'],
  113. 'description': info.get('body'),
  114. 'thumbnail': info.get('thumbnail') or info.get('poster'),
  115. 'duration': float_or_none(info.get('runtime'), 1000) or parse_duration(info.get('time')),
  116. 'upload_date': info['fid'].split('/')[-1][:8] if isinstance(info.get('fid'), compat_str) else None,
  117. 'uploader': info.get('nickname'),
  118. 'uploader_id': info.get('upload_userid'),
  119. 'view_count': str_to_int(info.get('hit')),
  120. 'like_count': str_to_int(info.get('likecnt')),
  121. 'formats': formats,
  122. }