2 from __future__ 
import unicode_literals
 
   6 from .common 
import InfoExtractor
 
   8     compat_urllib_parse_urlparse
, 
  19 class AfreecaTVIE(InfoExtractor
): 
  20     IE_DESC 
= 'afreecatv.com' 
  21     _VALID_URL 
= r
'''(?x)^ 
  22         https?://(?:(live|afbbs|www)\.)?afreeca(?:tv)?\.com(?::\d+)? 
  24             /app/(?:index|read_ucc_bbs)\.cgi| 
  25             /player/[Pp]layer\.(?:swf|html)) 
  26         \?.*?\bnTitleNo=(?P<id>\d+)''' 
  28         'url': 'http://live.afreecatv.com:8079/app/index.cgi?szType=read_ucc_bbs&szBjId=dailyapril&nStationNo=16711924&nBbsNo=18605867&nTitleNo=36164052&szSkin=', 
  29         'md5': 'f72c89fe7ecc14c1b5ce506c4996046e', 
  33             'title': '데일리 에이프릴 요정들의 시상식!', 
  34             'thumbnail': 're:^https?://(?:video|st)img.afreecatv.com/.*$', 
  35             'uploader': 'dailyapril', 
  36             'uploader_id': 'dailyapril', 
  37             'upload_date': '20160503', 
  40         'url': 'http://afbbs.afreecatv.com:8080/app/read_ucc_bbs.cgi?nStationNo=16711924&nTitleNo=36153164&szBjId=dailyapril&nBbsNo=18605867', 
  43             'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'", 
  44             'thumbnail': 're:^https?://(?:video|st)img.afreecatv.com/.*$', 
  45             'uploader': 'dailyapril', 
  46             'uploader_id': 'dailyapril', 
  50             'md5': 'd8b7c174568da61d774ef0203159bf97', 
  54                 'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'", 
  55                 'upload_date': '20160502', 
  58             'md5': '58f2ce7f6044e34439ab2d50612ab02b', 
  62                 'title': "BJ유트루와 함께하는 '팅커벨 메이크업!'", 
  63                 'upload_date': '20160502', 
  67         'url': 'http://www.afreecatv.com/player/Player.swf?szType=szBjId=djleegoon&nStationNo=11273158&nBbsNo=13161095&nTitleNo=36327652', 
  68         'only_matching': True, 
  72     def parse_video_key(key
): 
  74         m 
= re
.match(r
'^(?P<upload_date>\d{8})_\w+_(?P<part>\d+)$', key
) 
  76             video_key
['upload_date'] = m
.group('upload_date') 
  77             video_key
['part'] = m
.group('part') 
  80     def _real_extract(self
, url
): 
  81         video_id 
= self
._match
_id
(url
) 
  82         parsed_url 
= compat_urllib_parse_urlparse(url
) 
  83         info_url 
= compat_urlparse
.urlunparse(parsed_url
._replace
( 
  84             netloc
='afbbs.afreecatv.com:8080', 
  85             path
='/api/video/get_video_info.php')) 
  86         video_xml 
= self
._download
_xml
(info_url
, video_id
) 
  88         if xpath_element(video_xml
, './track/video/file') is None: 
  89             raise ExtractorError('Specified AfreecaTV video does not exist', 
  92         title 
= xpath_text(video_xml
, './track/title', 'title') 
  93         uploader 
= xpath_text(video_xml
, './track/nickname', 'uploader') 
  94         uploader_id 
= xpath_text(video_xml
, './track/bj_id', 'uploader id') 
  95         duration 
= int_or_none(xpath_text(video_xml
, './track/duration', 
  97         thumbnail 
= xpath_text(video_xml
, './track/titleImage', 'thumbnail') 
 100         for i
, video_file 
in enumerate(video_xml
.findall('./track/video/file')): 
 101             video_key 
= self
.parse_video_key(video_file
.get('key', '')) 
 105                 'id': '%s_%s' % (video_id
, video_key
.get('part', i 
+ 1)), 
 107                 'upload_date': video_key
.get('upload_date'), 
 108                 'duration': int_or_none(video_file
.get('duration')), 
 109                 'url': video_file
.text
, 
 115             'uploader': uploader
, 
 116             'uploader_id': uploader_id
, 
 117             'duration': duration
, 
 118             'thumbnail': thumbnail
, 
 122             info
['_type'] = 'multi_video' 
 123             info
['entries'] = entries
 
 124         elif len(entries
) == 1: 
 125             info
['url'] = entries
[0]['url'] 
 126             info
['upload_date'] = entries
[0].get('upload_date') 
 128             raise ExtractorError( 
 129                 'No files found for the specified AfreecaTV video, either' 
 130                 ' the URL is incorrect or the video has been made private.',