Merge branch 'fix-iqiyi' of https://github.com/zhangn1985/you-get into zhangn1985-fix-iqiyi

This commit is contained in:
Mort Yao 2016-07-01 06:31:51 +02:00
commit 919b2e65a8
No known key found for this signature in database
GPG Key ID: 07DA00CB78203251
2 changed files with 60 additions and 113 deletions

View File

@ -8,11 +8,10 @@ import json
from math import floor from math import floor
from zlib import decompress from zlib import decompress
import hashlib import hashlib
from ..util import log
import time import time
from .iqiyi_sc import gen_sc
''' '''
Changelog: Changelog:
-> http://www.iqiyi.com/common/flashplayer/20150916/MainPlayer_5_2_28_c3_3_7_4.swf -> http://www.iqiyi.com/common/flashplayer/20150916/MainPlayer_5_2_28_c3_3_7_4.swf
@ -81,31 +80,36 @@ def getDispathKey(rid):
t=str(int(floor(int(time)/(10*60.0)))) t=str(int(floor(int(time)/(10*60.0))))
return hashlib.new("md5",bytes(t+tp+rid,"utf-8")).hexdigest() return hashlib.new("md5",bytes(t+tp+rid,"utf-8")).hexdigest()
''' '''
def getVMS(tvid, vid):
t = int(time.time() * 1000)
src = '76f90cbd92f94a2e925d83e8ccd22cb7'
key = 'd5fb4bd9d50c4be6948c97edd7254b0e'
sc = hashlib.new('md5', bytes(str(t) + key + vid, 'utf-8')).hexdigest()
vmsreq= url = 'http://cache.m.iqiyi.com/tmts/{0}/{1}/?t={2}&sc={3}&src={4}'.format(tvid,vid,t,sc,src)
return json.loads(get_content(vmsreq))
class Iqiyi(VideoExtractor): class Iqiyi(VideoExtractor):
name = "爱奇艺 (Iqiyi)" name = "爱奇艺 (Iqiyi)"
stream_types = [ stream_types = [
{'id': 'high', 'container': 'mp4', 'video_profile': '高清'}, {'id': '4k', 'container': 'm3u8', 'video_profile': '4k'},
{'id': 'standard', 'container': 'mp4', 'video_profile': '标清'}, {'id': 'BD', 'container': 'm3u8', 'video_profile': '1080p'},
{'id': 'TD', 'container': 'm3u8', 'video_profile': '720p'},
{'id': 'HD', 'container': 'm3u8', 'video_profile': '540p'},
{'id': 'SD', 'container': 'm3u8', 'video_profile': '360p'},
{'id': 'LD', 'container': 'm3u8', 'video_profile': '210p'},
] ]
'''
supported_stream_types = [ 'high', 'standard'] supported_stream_types = [ 'high', 'standard']
stream_to_bid = { '4k': 10, 'fullhd' : 5, 'suprt-high' : 4, 'super' : 3, 'high' : 2, 'standard' :1, 'topspeed' :96} stream_to_bid = { '4k': 10, 'fullhd' : 5, 'suprt-high' : 4, 'super' : 3, 'high' : 2, 'standard' :1, 'topspeed' :96}
'''
ids = ['4k','BD', 'TD', 'HD', 'SD', 'LD']
vd_2_id = {10: '4k', 19: '4k', 5:'BD', 18: 'BD', 21: 'HD', 2: 'HD', 4: 'TD', 17: 'TD', 96: 'LD', 1: 'SD'}
id_2_profile = {'4k':'4k', 'BD': '1080p','TD': '720p', 'HD': '540p', 'SD': '360p', 'LD': '210p'}
def getVMS(self,rate):
#tm ->the flash run time for md5 usage
#um -> vip 1 normal 0
#authkey -> for password protected video ,replace '' with your password
#puid user.passportid may empty?
#TODO: support password protected video
tvid, vid = self.vid
t = int(time.time() * 1000)
sc = gen_sc(tvid, t).decode('utf-8')
vmsreq= 'http://cache.m.iqiyi.com/jp/tmts/{}/{}/?platForm=h5&rate={}&tvid={}&vid={}&cupid=qc_100001_100186&type=mp4&olimit=0&agenttype=13&src=d846d0c32d664d32b6b54ea48997a589&sc={}&t={}&__jsT=null'.format(tvid, vid, rate, tvid, vid, sc, t - 7)
return json.loads(get_content(vmsreq)[13:])
def download_playlist_by_url(self, url, **kwargs): def download_playlist_by_url(self, url, **kwargs):
self.url = url self.url = url
@ -128,12 +132,47 @@ class Iqiyi(VideoExtractor):
r1(r'vid=([^&]+)', self.url) or \ r1(r'vid=([^&]+)', self.url) or \
r1(r'data-player-videoid="([^"]+)"', html) r1(r'data-player-videoid="([^"]+)"', html)
self.vid = (tvid, videoid) self.vid = (tvid, videoid)
self.title = match1(html, '<title>([^<]+)').split('-')[0]
tvid, videoid = self.vid
info = getVMS(tvid, videoid)
assert info['code'] == 'A00000', 'can\'t play this video'
for stream in self.supported_stream_types: for stream in info['data']['vidl']:
info = self.getVMS(self.stream_to_bid[stream]) try:
if info["code"] == "A00000": stream_id = self.vd_2_id[stream['vd']]
self.title = info['data']['playInfo']['vn'] if stream_id in self.stream_types:
self.streams[stream] = {'container': 'mp4', 'video_profile': stream, 'src' : [info['data']['m3u']], 'size' : url_size(info['data']['m3u'])} continue
stream_profile = self.id_2_profile[stream_id]
self.streams[stream_id] = {'video_profile': stream_profile, 'container': 'm3u8', 'src': [stream['m3u']], 'size' : 0}
except:
log.i("vd: {} is not handled".format(stream['vd']))
log.i("info is {}".format(stream))
# why I need do below???
if not 'BD' in self.stream_types:
p1080_vids = []
if 18 in info['data']['ctl']['vip']['bids']:
p1080_vids.append(info['data']['ctl']['configs']['18']['vid'])
if 5 in info['data']['ctl']['vip']['bids']:
p1080_vids.append(info['data']['ctl']['configs']['5']['vid'])
for v in p1080_vids:
p1080_info = getVMS(tvid, v)
if info['code'] == 'A00000':
p1080_url = p1080_info['data']['m3u']
self.streams['BD'] = {'video_profile': '1080p', 'container': 'm3u8', 'src': [p1080_url], 'size' : 0}
break
if not '4k' in self.stream_types:
k4_vids = []
if 19 in info['data']['ctl']['vip']['bids']:
k4_vids.append(info['data']['ctl']['configs']['19']['vid'])
if 10 in info['data']['ctl']['vip']['bids']:
k4_vids.append(info['data']['ctl']['configs']['10']['vid'])
for v in k4_vids:
k4_info = getVMS(tvid, v)
if info['code'] == 'A00000':
k4_url = k4_info['data']['m3u']
self.streams['4k'] = {'video_profile': '4k', 'container': 'm3u8', 'src': [k4_url], 'size' : 0}
break
''' '''
if info["code"] != "A000000": if info["code"] != "A000000":
log.e("[error] outdated iQIYI key") log.e("[error] outdated iQIYI key")

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python
import binascii
import math
import time
M = [1732584193, -271733879]
M.extend([~M[0], ~M[1]])
I_table = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21]
C_base = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8388608, 432]
def L(n, t):
if t is None:
t = 0
return trunc(((n >> 1) + (t >> 1) << 1) + (n & 1) + (t & 1))
def rshift(val, n):
return val >> n if val >= 0 else (val+0x100000000) >> n
def trunc(n):
n = n % 0x100000000
if n > 0x7fffffff:
n -= 0x100000000
return n
def gen_sc(tvid, Z):
def transform(string, mod):
num = int(string, 16)
return (num >> 8 * (i % 4) & 255 ^ i % mod) << ((a & 3) << 3)
C = list(C_base)
o = list(M)
k = str(Z - 7)
for i in range(13):
a = i
C[a >> 2] |= ord(k[a]) << 8 * (a % 4)
for i in range(16):
a = i + 13
start = (i >> 2) * 8
r = '03967743b643f66763d623d637e30733'
C[a >> 2] |= transform(''.join(reversed(r[start:start + 8])), 7)
for i in range(16):
a = i + 29
start = (i >> 2) * 8
r = '7038766939776a32776a32706b337139'
C[a >> 2] |= transform(r[start:start + 8], 1)
for i in range(9):
a = i + 45
if i < len(tvid):
C[a >> 2] |= ord(tvid[i]) << 8 * (a % 4)
for a in range(64):
i = a
I = i >> 4
C_index = [i, 5 * i + 1, 3 * i + 5, 7 * i][I] % 16 + rshift(a, 6)
m = L(
L(
o[0],
[
trunc(o[1] & o[2]) | trunc(~o[1] & o[3]),
trunc(o[3] & o[1]) | trunc(~o[3] & o[2]),
o[1] ^ o[2] ^ o[3],
o[2] ^ trunc(o[1] | ~o[3])
][I]
),
L(
trunc(int(abs(math.sin(i + 1)) * 4294967296)),
C[C_index] if C_index < len(C) else None
)
)
I = I_table[4 * I + i % 4]
o = [
o[3],
L(o[1], trunc(trunc(m << I) | rshift(m, 32 - I))),
o[1],
o[2],
]
new_M = [L(o[0], M[0]), L(o[1], M[1]), L(o[2], M[2]), L(o[3], M[3])]
s = [new_M[a >> 3] >> (1 ^ a & 7) * 4 & 15 for a in range(32)]
return binascii.hexlify(bytes(s))[1::2]
if __name__ == '__main__':
print(gen_sc("494496100", 1466495259194))
print(gen_sc("397768800", 1466795077775))
print(gen_sc("397768800", 1466796325746))