stream_id % 10 ** 3 if stream_id < 10 ** 4 else stream_id % 10 ** 4

This commit is contained in:
ivan 2017-02-24 13:23:07 +08:00
parent eeae0da6ed
commit c95d537fb4

View File

@ -17,6 +17,7 @@ ZERO_LEN = 7
SEED = 0xdead SEED = 0xdead
def rand(): def rand():
global SEED global SEED
if SEED == 0: if SEED == 0:
@ -28,12 +29,14 @@ def rand():
SEED = SEED + 2147483647 SEED = SEED + 2147483647
return SEED return SEED
def pack(data): def pack(data):
target = [] target = []
for i in data: for i in data:
target.extend(struct.pack('>I', i)) target.extend(struct.pack('>I', i))
return target return target
def unpack(data): def unpack(data):
data = bytes(data) data = bytes(data)
target = [] target = []
@ -41,6 +44,7 @@ def unpack(data):
target.extend(struct.unpack('>I', data[i:i + 4])) target.extend(struct.unpack('>I', data[i:i + 4]))
return target return target
def tea_encrypt(v, key): def tea_encrypt(v, key):
s = 0 s = 0
key = unpack(key) key = unpack(key)
@ -54,6 +58,7 @@ def tea_encrypt(v, key):
v[1] &= 0xffffffff v[1] &= 0xffffffff
return pack(v) return pack(v)
def oi_symmetry_encrypt2(raw_data, key): def oi_symmetry_encrypt2(raw_data, key):
pad_salt_body_zero_len = 1 + SALT_LEN + len(raw_data) + ZERO_LEN pad_salt_body_zero_len = 1 + SALT_LEN + len(raw_data) + ZERO_LEN
pad_len = pad_salt_body_zero_len % 8 pad_len = pad_salt_body_zero_len % 8
@ -86,6 +91,7 @@ KEY = [
0x39, 0x6, 0x33, 0xee, 0xfb, 0xbf, 0xf3, 0xb6 0x39, 0x6, 0x33, 0xee, 0xfb, 0xbf, 0xf3, 0xb6
] ]
def packstr(data): def packstr(data):
l = len(data) l = len(data)
t = [] t = []
@ -94,12 +100,14 @@ def packstr(data):
t.extend([ord(c) for c in data]) t.extend([ord(c) for c in data])
return t return t
def strsum(data): def strsum(data):
s = 0 s = 0
for c in data: for c in data:
s = s * 131 + c s = s * 131 + c
return 0x7fffffff & s return 0x7fffffff & s
def echo_ckeyv3(vid, guid='', t=None, player_version='3.2.38.401', platform=10902, stdfrom='bcng'): def echo_ckeyv3(vid, guid='', t=None, player_version='3.2.38.401', platform=10902, stdfrom='bcng'):
data = [] data = []
data.extend(pack([21507, 3168485562])) data.extend(pack([21507, 3168485562]))
@ -176,13 +184,18 @@ class QQ(VideoExtractor):
dict.__init__(self, **kwargs) dict.__init__(self, **kwargs)
self.stream_id = stream_id self.stream_id = stream_id
def _getfilename(self, lnk, stream_id, idx):
return '{lnk}.p{num}.{idx}.mp4'.format(lnk=lnk, num=stream_id % 10 ** 3 if stream_id < 10 ** 4 else stream_id % 10 ** 4, idx=idx)
def _getvkey(self, vid, format, idx): def _getvkey(self, vid, format, idx):
import uuid import uuid
appver = '3.2.38.401' appver = '3.2.38.401'
guid = uuid.uuid4().hex.upper() guid = uuid.uuid4().hex.upper()
platform = 11 platform = 11
cKey = echo_ckeyv3(vid=vid, guid=guid, player_version=appver, platform=platform) cKey = echo_ckeyv3(vid=vid, guid=guid, player_version=appver, platform=platform)
key_api = 'http://vv.video.qq.com/getvkey?vid={vid}&appver={appver}&platform={platform}&otype=json&filename={lnk}.p{format1000}.{idx}.mp4&format={format}&cKey={cKey}&guid={guid}&charge=1&encryptVer=5.4&lnk={vid}'.format(vid=vid, appver=appver, format1000=format%1000, format=format, cKey=cKey, guid=guid, platform=platform, idx=idx, lnk=lnk) key_api = 'http://vv.video.qq.com/getvkey?vid={vid}&appver={appver}&platform={platform}&otype=json&filename={filename}&format={format}&cKey={cKey}&guid={guid}&charge=1&encryptVer=5.4&lnk={vid}'.format(
vid=vid, appver=appver, filename=self._getfilename(lnk, format, idx),
format=format, cKey=cKey, guid=guid, platform=platform, lnk=lnk)
part_info = get_html(key_api) part_info = get_html(key_api)
key_json = json.loads(match1(part_info, r'QZOutputJson=(.*)')[:-1]) key_json = json.loads(match1(part_info, r'QZOutputJson=(.*)')[:-1])
return 'key' in key_json and key_json['key'] return 'key' in key_json and key_json['key']
@ -193,7 +206,7 @@ class QQ(VideoExtractor):
for idx in range(1, vi0['cl']['fc'] + 1): for idx in range(1, vi0['cl']['fc'] + 1):
vkey = self._getvkey(vid, self.stream_id, idx) vkey = self._getvkey(vid, self.stream_id, idx)
if vkey: if vkey:
url = '{prefix}/{lnk}.p{format1000}.{idx}.mp4?vkey={vkey}'.format(prefix=url_prefix, format1000=self.stream_id%1000, idx=idx, vkey=vkey, lnk=lnk) url = '{prefix}/{filename}?vkey={vkey}'.format(prefix=url_prefix, filename=self._getfilename(lnk=lnk, stream_id=self.stream_id, idx=idx), vkey=vkey)
self['src'].append(url) self['src'].append(url)
return self['src'] return self['src']
else: else:
@ -249,7 +262,8 @@ def qq_download(url, output_dir='.', merge=True, info_only=False, **kwargs):
title = vid title = vid
else: else:
content = get_html(url) content = get_html(url)
vid = parse_qs(urlparse(url).query).get('vid') #for links specified vid like http://v.qq.com/cover/p/ps6mnfqyrfo7es3.html?vid=q0181hpdvo5 vid = parse_qs(urlparse(url).query).get(
'vid') # for links specified vid like http://v.qq.com/cover/p/ps6mnfqyrfo7es3.html?vid=q0181hpdvo5
vid = vid[0] if vid else match1(content, r'vid"*\s*:\s*"\s*([^"]+)"') # general fallback vid = vid[0] if vid else match1(content, r'vid"*\s*:\s*"\s*([^"]+)"') # general fallback
title = match1(content, r'<a.*?id\s*=\s*"%s".*?title\s*=\s*"(.+?)".*?>' % vid) title = match1(content, r'<a.*?id\s*=\s*"%s".*?title\s*=\s*"(.+?)".*?>' % vid)
title = match1(content, r'title">([^"]+)</p>') if not title else title title = match1(content, r'title">([^"]+)</p>') if not title else title
@ -258,6 +272,7 @@ def qq_download(url, output_dir='.', merge=True, info_only=False, **kwargs):
site.download_by_vid(vid=vid, output_dir=output_dir, merge=merge, info_only=info_only, **kwargs) site.download_by_vid(vid=vid, output_dir=output_dir, merge=merge, info_only=info_only, **kwargs)
qq_download_by_vid = site.download_by_vid qq_download_by_vid = site.download_by_vid
site_info = "QQ.com" site_info = "QQ.com"
download = qq_download download = qq_download