From ff7b57a0657fb467c10bb74c6b34f1e29dcde87f Mon Sep 17 00:00:00 2001 From: Mort Yao Date: Thu, 7 Aug 2014 21:21:35 +0200 Subject: [PATCH] Youku: fix #383, using the new ep generation algorithm --- src/you_get/extractors/youku.py | 53 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/you_get/extractors/youku.py b/src/you_get/extractors/youku.py index 0f2d593..9b2c402 100644 --- a/src/you_get/extractors/youku.py +++ b/src/you_get/extractors/youku.py @@ -4,6 +4,9 @@ from ..common import * from ..extractor import VideoExtractor +import base64 +import time + class Youku(VideoExtractor): name = "优酷 (Youku)" @@ -17,6 +20,36 @@ class Youku(VideoExtractor): {'id': '3gphd', 'container': '3gp', 'video_profile': '高清(3GP)'}, ] + def generate_ep(vid, ep): + f_code_1 = 'becaf9be' + f_code_2 = 'bf7e5f01' + + def trans_e(a, c): + f = h = 0 + b = list(range(256)) + result = '' + while h < 256: + f = (f + b[h] + ord(a[h % len(a)])) % 256 + b[h], b[f] = b[f], b[h] + h += 1 + q = f = h = 0 + while q < len(c): + h = (h + 1) % 256 + f = (f + b[h]) % 256 + b[h], b[f] = b[f], b[h] + if isinstance(c[q], int): + result += chr(c[q] ^ b[(b[h] + b[f]) % 256]) + else: + result += chr(ord(c[q]) ^ b[(b[h] + b[f]) % 256]) + q += 1 + + return result + + e_code = trans_e(f_code_1, base64.b64decode(ep)) + sid, token = e_code.split('_') + new_ep = trans_e(f_code_2, '%s_%s_%s' % (sid, vid, token)) + return base64.b64encode(bytes(new_ep, 'latin')), sid, token + def parse_m3u8(m3u8): return re.findall(r'(http://[^?]+)\?ts_start=0', m3u8) @@ -57,7 +90,7 @@ class Youku(VideoExtractor): self.download_playlist_by_url(self.url, **kwargs) exit(0) - meta = json.loads(get_html('http://v.youku.com/player/getPlayList/VideoIDS/%s' % self.vid)) + meta = json.loads(get_html('http://v.youku.com/player/getPlayList/VideoIDS/%s/Pf/4/ctype/12/ev/1' % self.vid)) if not meta['data']: log.wtf('[Failed] Video not found.') metadata0 = meta['data'][0] @@ -72,6 +105,9 @@ class Youku(VideoExtractor): self.title = metadata0['title'] + self.ep = metadata0['ep'] + self.ip = metadata0['ip'] + if 'dvd' in metadata0 and 'audiolang' in metadata0['dvd']: self.audiolang = metadata0['dvd']['audiolang'] for i in self.audiolang: @@ -102,7 +138,20 @@ class Youku(VideoExtractor): # Extract stream with the best quality stream_id = self.streams_sorted[0]['id'] - m3u8_url = "http://v.youku.com/player/getM3U8/vid/{vid}/type/{stream_id}/video.m3u8".format(vid=self.vid, stream_id=stream_id) + new_ep, sid, token = __class__.generate_ep(self.vid, self.ep) + m3u8_query = parse.urlencode(dict( + ctype=12, + ep=new_ep, + ev=1, + keyframe=1, + oip=self.ip, + sid=sid, + token=token, + ts=int(time.time()), + type=stream_id, + vid=self.vid, + )) + m3u8_url = 'http://pl.youku.com/playlist/m3u8?' + m3u8_query if not kwargs['info_only']: if self.password_protected: -- GitLab