From 58efc40ccb95149027a24098bba8e2db95bf0d9a Mon Sep 17 00:00:00 2001 From: David Zhuang Date: Thu, 28 Apr 2016 01:27:44 -0400 Subject: [PATCH] [Youku]Add COOP platform --- src/you_get/extractors/youku.py | 63 ++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/you_get/extractors/youku.py b/src/you_get/extractors/youku.py index 3135e822..fefaf5ee 100644 --- a/src/you_get/extractors/youku.py +++ b/src/you_get/extractors/youku.py @@ -28,7 +28,11 @@ class Youku(VideoExtractor): f_code_1 = 'becaf9be' f_code_2 = 'bf7e5f01' + ctype = 12 #differ from 86 + def trans_e(a, c): + """str, str->str + This is an RC4 encryption.""" f = h = 0 b = list(range(256)) result = '' @@ -49,14 +53,14 @@ class Youku(VideoExtractor): return result - def generate_ep(no, streamfileids, sid, token): + def generate_ep(self, no, streamfileids, sid, token): number = hex(int(str(no), 10))[2:].upper() if len(number) == 1: number = '0' + number fileid = streamfileids[0:8] + number + streamfileids[10:] ep = parse.quote(base64.b64encode( - ''.join(Youku.trans_e( - Youku.f_code_2, + ''.join(self.__class__.trans_e( + self.f_code_2, #use the 86 fcode if using 86 sid + '_' + fileid + '_' + token)).encode('latin1')), safe='~()*!.\'' ) @@ -150,8 +154,17 @@ class Youku(VideoExtractor): self.download_playlist_by_url(self.url, **kwargs) exit(0) - api_url = 'http://play.youku.com/play/get.json?vid=%s&ct=10' % self.vid - api12_url = 'http://play.youku.com/play/get.json?vid=%s&ct=12' % self.vid + #HACK! + if 'api_url' in kwargs: + api_url = kwargs['api_url'] #85 + api12_url = kwargs['api12_url'] #86 + self.ctype = kwargs['ctype'] + self.title = kwargs['title'] + + else: + api_url = 'http://play.youku.com/play/get.json?vid=%s&ct=10' % self.vid + api12_url = 'http://play.youku.com/play/get.json?vid=%s&ct=12' % self.vid + try: meta = json.loads(get_content( api_url, @@ -187,7 +200,8 @@ class Youku(VideoExtractor): else: log.wtf('[Failed] Video not found.') - self.title = data['video']['title'] + if not self.title: #86 + self.title = data['video']['title'] self.ep = data12['security']['encrypt_string'] self.ip = data12['security']['ip'] @@ -264,7 +278,7 @@ class Youku(VideoExtractor): stream_id = self.streams_sorted[0]['id'] e_code = self.__class__.trans_e( - self.__class__.f_code_1, + self.f_code_1, base64.b64decode(bytes(self.ep, 'ascii')) ) sid, token = e_code.split('_') @@ -279,10 +293,10 @@ class Youku(VideoExtractor): for no in range(0, len(segs)): k = segs[no]['key'] if k == -1: break # we hit the paywall; stop here - fileid, ep = self.__class__.generate_ep(no, streamfileid, + fileid, ep = self.__class__.generate_ep(self, no, streamfileid, sid, token) q = parse.urlencode(dict( - ctype = 12, + ctype = self.ctype, ev = 1, K = k, ep = parse.unquote(ep), @@ -312,9 +326,40 @@ class Youku(VideoExtractor): if not kwargs['info_only']: self.streams[stream_id]['src'] = ksegs + def open_download_by_vid(self, client_id, vid, **kwargs): + """self, str, str, **kwargs->None + Override the original one with VideoExtractor. + Most of the credit are to @ERioK, who gave his POC.""" + self.f_code_1 = '10ehfkbv' #can be retrived by running r.translate with the keys and the list e + self.f_code_2 = 'msjv7h2b' + self.url = None + self.vid = vid + self.name = "优酷开放平台 (Youku COOP)" + + #A little bit of work before self.prepare + sign_url = "https://api.youku.com/players/custom.json?client_id={client_id}&video_id={video_id}".format(client_id = client_id, video_id = vid) + playsign = json.loads(get_content(sign_url))['playsign'] + + api85_url = 'http://play.youku.com/partner/get.json?cid={client_id}&vid={vid}&ct=85&sign={playsign}'.format(client_id = client_id, vid = vid, playsign = playsign) + api86_url = 'http://play.youku.com/partner/get.json?cid={client_id}&vid={vid}&ct=86&sign={playsign}'.format(client_id = client_id, vid = vid, playsign = playsign) + + self.prepare(api_url = api85_url, api12_url = api86_url, ctype = 86, **kwargs) + if 'extractor_proxy' in kwargs and kwargs['extractor_proxy']: + unset_proxy() + + try: + self.streams_sorted = [dict([('id', stream_type['id'])] + list(self.streams[stream_type['id']].items())) for stream_type in self.__class__.stream_types if stream_type['id'] in self.streams] + except: + self.streams_sorted = [dict([('itag', stream_type['itag'])] + list(self.streams[stream_type['itag']].items())) for stream_type in self.__class__.stream_types if stream_type['itag'] in self.streams] + + self.extract(**kwargs) + + self.download(**kwargs) + site = Youku() download = site.download_by_url download_playlist = site.download_playlist_by_url youku_download_by_vid = site.download_by_vid +youku_open_download_by_vid = site.open_download_by_vid # Used by: acfun.py bilibili.py miomio.py tudou.py