2012-09-01 22:32:08 +04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
__all__ = ['iqiyi_download']
|
|
|
|
|
|
|
|
from ..common import *
|
2014-09-01 16:19:42 +04:00
|
|
|
from uuid import uuid4
|
|
|
|
from random import random,randint
|
|
|
|
import json
|
|
|
|
from math import floor
|
2015-05-15 12:17:28 +03:00
|
|
|
from zlib import decompress
|
2014-09-01 16:19:42 +04:00
|
|
|
import hashlib
|
|
|
|
|
2015-05-12 17:58:17 +03:00
|
|
|
'''
|
|
|
|
Changelog:
|
2015-06-19 18:54:50 +03:00
|
|
|
-> http://www.iqiyi.com/common/flashplayer/20150618/MainPlayer_5_2_24_1_c3_3_2.swf
|
|
|
|
In this version Z7elzzup.cexe,just use node.js to run this code(with some modification) and get innerkey.
|
|
|
|
|
2015-06-13 07:11:32 +03:00
|
|
|
-> http://www.iqiyi.com/common/flashplayer/20150612/MainPlayer_5_2_23_1_c3_2_6_5.swf
|
|
|
|
In this version do not directly use enc key
|
|
|
|
gen enc key (so called sc ) in DMEmagelzzup.mix(tvid) -> (tm->getTimer(),src='hsalf',sc)
|
|
|
|
encrypy alogrithm is md5(DMEmagelzzup.mix.genInnerKey +tm+tvid)
|
|
|
|
how to gen genInnerKey ,can see first 3 lin in mix function in this file
|
2015-05-12 17:58:17 +03:00
|
|
|
'''
|
|
|
|
|
2014-09-01 16:19:42 +04:00
|
|
|
'''
|
|
|
|
com.qiyi.player.core.model.def.DefinitonEnum
|
|
|
|
bid meaning for quality
|
|
|
|
0 none
|
|
|
|
1 standard
|
|
|
|
2 high
|
|
|
|
3 super
|
|
|
|
4 suprt-high
|
|
|
|
5 fullhd
|
|
|
|
10 4k
|
|
|
|
96 topspeed
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
2015-06-13 07:11:32 +03:00
|
|
|
def mix(tvid):
|
|
|
|
enc = []
|
2015-06-19 18:54:50 +03:00
|
|
|
enc.append('7b11c5408ff342318da3e7c97b92e890')
|
2015-06-19 19:11:19 +03:00
|
|
|
tm = str(randint(2000,4000))
|
2015-06-13 07:11:32 +03:00
|
|
|
src = 'hsalf'
|
|
|
|
enc.append(str(tm))
|
|
|
|
enc.append(tvid)
|
|
|
|
sc = hashlib.new('md5',bytes("".join(enc),'utf-8')).hexdigest()
|
|
|
|
return tm,sc,src
|
2015-05-12 17:58:17 +03:00
|
|
|
|
2014-09-01 16:19:42 +04:00
|
|
|
def getVRSXORCode(arg1,arg2):
|
|
|
|
loc3=arg2 %3
|
|
|
|
if loc3 == 1:
|
|
|
|
return arg1^121
|
|
|
|
if loc3 == 2:
|
|
|
|
return arg1^72
|
|
|
|
return arg1^103
|
|
|
|
|
|
|
|
|
|
|
|
def getVrsEncodeCode(vlink):
|
|
|
|
loc6=0
|
|
|
|
loc2=''
|
|
|
|
loc3=vlink.split("-")
|
|
|
|
loc4=len(loc3)
|
|
|
|
# loc5=loc4-1
|
|
|
|
for i in range(loc4-1,-1,-1):
|
|
|
|
loc6=getVRSXORCode(int(loc3[loc4-i-1],16),i)
|
|
|
|
loc2+=chr(loc6)
|
|
|
|
return loc2[::-1]
|
|
|
|
|
2015-06-13 07:11:32 +03:00
|
|
|
def getVMS(tvid,vid,uid):
|
2015-01-28 17:15:47 +03:00
|
|
|
#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
|
2015-06-13 07:11:32 +03:00
|
|
|
tm,sc,src = mix(tvid)
|
2015-01-28 17:15:47 +03:00
|
|
|
vmsreq='http://cache.video.qiyi.com/vms?key=fvip&src=1702633101b340d8917a69cf8a4b8c7' +\
|
2015-06-13 07:11:32 +03:00
|
|
|
"&tvId="+tvid+"&vid="+vid+"&vinfo=1&tm="+tm+\
|
|
|
|
"&enc="+sc+\
|
2015-01-28 17:15:47 +03:00
|
|
|
"&qyid="+uid+"&tn="+str(random()) +"&um=0" +\
|
|
|
|
"&authkey="+hashlib.new('md5',bytes(''+str(tm)+tvid,'utf-8')).hexdigest()
|
2015-01-28 17:17:07 +03:00
|
|
|
return json.loads(get_content(vmsreq))
|
2014-09-01 16:19:42 +04:00
|
|
|
|
|
|
|
def getDispathKey(rid):
|
|
|
|
tp=")(*&^flash@#$%a" #magic from swf
|
|
|
|
time=json.loads(get_content("http://data.video.qiyi.com/t?tn="+str(random())))["t"]
|
|
|
|
t=str(int(floor(int(time)/(10*60.0))))
|
|
|
|
return hashlib.new("md5",bytes(t+tp+rid,"utf-8")).hexdigest()
|
|
|
|
|
2012-09-01 22:32:08 +04:00
|
|
|
|
|
|
|
def iqiyi_download(url, output_dir = '.', merge = True, info_only = False):
|
2014-09-01 16:19:42 +04:00
|
|
|
gen_uid=uuid4().hex
|
|
|
|
|
2012-09-01 22:32:08 +04:00
|
|
|
html = get_html(url)
|
2015-05-15 12:17:28 +03:00
|
|
|
|
2014-05-29 04:27:38 +04:00
|
|
|
tvid = r1(r'data-player-tvid="([^"]+)"', html)
|
|
|
|
videoid = r1(r'data-player-videoid="([^"]+)"', html)
|
2015-05-15 12:17:28 +03:00
|
|
|
|
2014-05-29 04:27:38 +04:00
|
|
|
assert tvid
|
|
|
|
assert videoid
|
|
|
|
|
2015-06-13 07:11:32 +03:00
|
|
|
info = getVMS(tvid, videoid, gen_uid)
|
2015-05-15 12:17:28 +03:00
|
|
|
|
2015-01-28 17:15:47 +03:00
|
|
|
assert info["code"] == "A000000"
|
2014-09-01 16:19:42 +04:00
|
|
|
|
|
|
|
title = info["data"]["vi"]["vn"]
|
|
|
|
|
2015-01-28 17:15:47 +03:00
|
|
|
# data.vp = json.data.vp
|
|
|
|
# data.vi = json.data.vi
|
|
|
|
# data.f4v = json.data.f4v
|
|
|
|
# if movieIsMember data.vp = json.data.np
|
|
|
|
|
2014-09-01 16:19:42 +04:00
|
|
|
#for highest qualities
|
2014-09-02 04:11:31 +04:00
|
|
|
#for http://www.iqiyi.com/v_19rrmmz5yw.html not vp -> np
|
|
|
|
try:
|
2014-09-21 07:14:43 +04:00
|
|
|
if info["data"]['vp']["tkl"]=='' :
|
2014-09-02 04:11:31 +04:00
|
|
|
raise ValueError
|
|
|
|
except:
|
|
|
|
log.e("[Error] Do not support for iQIYI VIP video.")
|
|
|
|
exit(-1)
|
|
|
|
|
2014-09-01 16:19:42 +04:00
|
|
|
bid=0
|
|
|
|
for i in info["data"]["vp"]["tkl"][0]["vs"]:
|
|
|
|
if int(i["bid"])<=10 and int(i["bid"])>=bid:
|
|
|
|
bid=int(i["bid"])
|
2015-01-30 09:01:31 +03:00
|
|
|
|
|
|
|
video_links=i["fs"] #now in i["flvs"] not in i["fs"]
|
|
|
|
if not i["fs"][0]["l"].startswith("/"):
|
|
|
|
tmp = getVrsEncodeCode(i["fs"][0]["l"])
|
|
|
|
if tmp.endswith('mp4'):
|
|
|
|
video_links = i["flvs"]
|
|
|
|
|
2014-09-01 16:19:42 +04:00
|
|
|
|
|
|
|
urls=[]
|
|
|
|
size=0
|
|
|
|
for i in video_links:
|
|
|
|
vlink=i["l"]
|
|
|
|
if not vlink.startswith("/"):
|
|
|
|
#vlink is encode
|
|
|
|
vlink=getVrsEncodeCode(vlink)
|
|
|
|
key=getDispathKey(vlink.split("/")[-1].split(".")[0])
|
2015-01-28 17:15:47 +03:00
|
|
|
size+=i["b"]
|
2014-09-01 16:19:42 +04:00
|
|
|
baseurl=info["data"]["vp"]["du"].split("/")
|
|
|
|
baseurl.insert(-1,key)
|
2015-01-28 17:15:47 +03:00
|
|
|
url="/".join(baseurl)+vlink+'?su='+gen_uid+'&qyid='+uuid4().hex+'&client=&z=&bt=&ct=&tn='+str(randint(10000,20000))
|
2014-09-01 16:19:42 +04:00
|
|
|
urls.append(json.loads(get_content(url))["l"])
|
|
|
|
#download should be complete in 10 minutes
|
|
|
|
#because the url is generated before start downloading
|
|
|
|
#and the key may be expired after 10 minutes
|
2013-01-25 00:12:15 +04:00
|
|
|
print_info(site_info, title, 'flv', size)
|
2012-09-01 22:32:08 +04:00
|
|
|
if not info_only:
|
2013-01-25 00:12:15 +04:00
|
|
|
download_urls(urls, title, 'flv', size, output_dir = output_dir, merge = merge)
|
2012-09-01 22:32:08 +04:00
|
|
|
|
|
|
|
site_info = "iQIYI.com"
|
|
|
|
download = iqiyi_download
|
|
|
|
download_playlist = playlist_not_supported('iqiyi')
|