Merge pull request #1089 from cnbeining/acfun-fix-youku

Acfun: Fix Youku COOP ct85&86
This commit is contained in:
David Zhuang 2016-04-28 01:44:08 -04:00
commit 2c46060c6d
2 changed files with 60 additions and 18 deletions

15
src/you_get/extractors/acfun.py Normal file → Executable file
View File

@ -8,7 +8,7 @@ from .le import letvcloud_download_by_vu
from .qq import qq_download_by_vid
from .sina import sina_download_by_vid
from .tudou import tudou_download_by_iid
from .youku import youku_download_by_vid
from .youku import youku_download_by_vid, youku_open_download_by_vid
import json, re
@ -32,14 +32,11 @@ def acfun_download_by_vid(vid, title, output_dir='.', merge=True, info_only=Fals
elif sourceType == 'letv':
letvcloud_download_by_vu(sourceId, '2d8c027396', title, output_dir=output_dir, merge=merge, info_only=info_only)
elif sourceType == 'zhuzhan':
a = 'http://api.aixifan.com/plays/%s/realSource' % vid
s = json.loads(get_content(a, headers={'deviceType': '1'}))
urls = s['data']['files'][-1]['url']
size = urls_size(urls)
print_info(site_info, title, 'mp4', size)
if not info_only:
download_urls(urls, title, 'mp4', size,
output_dir=output_dir, merge=merge)
a = 'http://api.aixifan.com/plays/%s' % vid
s = json.loads(get_content(a, headers={'deviceType': '2'}))
if s['data']['source'] == "zhuzhan-youku":
sourceId = s['data']['sourceId']
youku_open_download_by_vid(client_id='908a519d032263f8', vid=sourceId, title=title, output_dir=output_dir, merge=merge, info_only=info_only, **kwargs)
else:
raise NotImplementedError(sourceType)

View File

@ -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