pandoratv.py 4.5 KB

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