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.

133 lines
4.9 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..compat import (
  6. compat_urllib_parse_urlparse,
  7. compat_urlparse,
  8. )
  9. from ..utils import (
  10. ExtractorError,
  11. int_or_none,
  12. xpath_element,
  13. xpath_text,
  14. )
  15. class AfreecaTVIE(InfoExtractor):
  16. IE_DESC = 'afreecatv.com'
  17. _VALID_URL = r'''(?x)^
  18. https?://(?:(live|afbbs|www)\.)?afreeca(?:tv)?\.com(?::\d+)?
  19. (?:
  20. /app/(?:index|read_ucc_bbs)\.cgi|
  21. /player/[Pp]layer\.(?:swf|html))
  22. \?.*?\bnTitleNo=(?P<id>\d+)'''
  23. _TESTS = [{
  24. 'url': 'http://live.afreecatv.com:8079/app/index.cgi?szType=read_ucc_bbs&szBjId=dailyapril&nStationNo=16711924&nBbsNo=18605867&nTitleNo=36164052&szSkin=',
  25. 'md5': 'f72c89fe7ecc14c1b5ce506c4996046e',
  26. 'info_dict': {
  27. 'id': '36164052',
  28. 'ext': 'mp4',
  29. 'title': '데일리 에이프릴 요정들의 시상식!',
  30. 'thumbnail': 're:^https?://(?:video|st)img.afreecatv.com/.*$',
  31. 'uploader': 'dailyapril',
  32. 'uploader_id': 'dailyapril',
  33. 'upload_date': '20160503',
  34. }
  35. }, {
  36. 'url': 'http://afbbs.afreecatv.com:8080/app/read_ucc_bbs.cgi?nStationNo=16711924&nTitleNo=36153164&szBjId=dailyapril&nBbsNo=18605867',
  37. 'info_dict': {
  38. 'id': '36153164',
  39. 'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'",
  40. 'thumbnail': 're:^https?://(?:video|st)img.afreecatv.com/.*$',
  41. 'uploader': 'dailyapril',
  42. 'uploader_id': 'dailyapril',
  43. },
  44. 'playlist_count': 2,
  45. 'playlist': [{
  46. 'md5': 'd8b7c174568da61d774ef0203159bf97',
  47. 'info_dict': {
  48. 'id': '36153164_1',
  49. 'ext': 'mp4',
  50. 'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'",
  51. 'upload_date': '20160502',
  52. },
  53. }, {
  54. 'md5': '58f2ce7f6044e34439ab2d50612ab02b',
  55. 'info_dict': {
  56. 'id': '36153164_2',
  57. 'ext': 'mp4',
  58. 'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'",
  59. 'upload_date': '20160502',
  60. },
  61. }],
  62. }, {
  63. 'url': 'http://www.afreecatv.com/player/Player.swf?szType=szBjId=djleegoon&nStationNo=11273158&nBbsNo=13161095&nTitleNo=36327652',
  64. 'only_matching': True,
  65. }]
  66. @staticmethod
  67. def parse_video_key(key):
  68. video_key = {}
  69. m = re.match(r'^(?P<upload_date>\d{8})_\w+_(?P<part>\d+)$', key)
  70. if m:
  71. video_key['upload_date'] = m.group('upload_date')
  72. video_key['part'] = m.group('part')
  73. return video_key
  74. def _real_extract(self, url):
  75. video_id = self._match_id(url)
  76. parsed_url = compat_urllib_parse_urlparse(url)
  77. info_url = compat_urlparse.urlunparse(parsed_url._replace(
  78. netloc='afbbs.afreecatv.com:8080',
  79. path='/api/video/get_video_info.php'))
  80. video_xml = self._download_xml(info_url, video_id)
  81. if xpath_element(video_xml, './track/video/file') is None:
  82. raise ExtractorError('Specified AfreecaTV video does not exist',
  83. expected=True)
  84. title = xpath_text(video_xml, './track/title', 'title')
  85. uploader = xpath_text(video_xml, './track/nickname', 'uploader')
  86. uploader_id = xpath_text(video_xml, './track/bj_id', 'uploader id')
  87. duration = int_or_none(xpath_text(video_xml, './track/duration',
  88. 'duration'))
  89. thumbnail = xpath_text(video_xml, './track/titleImage', 'thumbnail')
  90. entries = []
  91. for i, video_file in enumerate(video_xml.findall('./track/video/file')):
  92. video_key = self.parse_video_key(video_file.get('key', ''))
  93. if not video_key:
  94. continue
  95. entries.append({
  96. 'id': '%s_%s' % (video_id, video_key.get('part', i + 1)),
  97. 'title': title,
  98. 'upload_date': video_key.get('upload_date'),
  99. 'duration': int_or_none(video_file.get('duration')),
  100. 'url': video_file.text,
  101. })
  102. info = {
  103. 'id': video_id,
  104. 'title': title,
  105. 'uploader': uploader,
  106. 'uploader_id': uploader_id,
  107. 'duration': duration,
  108. 'thumbnail': thumbnail,
  109. }
  110. if len(entries) > 1:
  111. info['_type'] = 'multi_video'
  112. info['entries'] = entries
  113. elif len(entries) == 1:
  114. info['url'] = entries[0]['url']
  115. info['upload_date'] = entries[0].get('upload_date')
  116. else:
  117. raise ExtractorError(
  118. 'No files found for the specified AfreecaTV video, either'
  119. ' the URL is incorrect or the video has been made private.',
  120. expected=True)
  121. return info