rewrit iqiyi using VideoExtractor class

Signed-off-by: Zhang Ning <zhangn1985@gmail.com>
This commit is contained in:
Zhang Ning 2015-09-05 17:15:57 +08:00
parent 7bdf8af620
commit 5b56b1c8f7

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
__all__ = ['iqiyi_download']
from ..common import * from ..common import *
from ..extractor import VideoExtractor
from uuid import uuid4 from uuid import uuid4
from random import random,randint from random import random,randint
import json import json
@ -44,7 +43,6 @@ bid meaning for quality
96 topspeed 96 topspeed
''' '''
def mix(tvid): def mix(tvid):
enc = [] enc = []
enc.append('3cba91f1453145438ac5e4f5983bc086') enc.append('3cba91f1453145438ac5e4f5983bc086')
@ -75,13 +73,41 @@ def getVrsEncodeCode(vlink):
loc2+=chr(loc6) loc2+=chr(loc6)
return loc2[::-1] return loc2[::-1]
def getVMS(tvid,vid,uid): 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()
class Iqiyi(VideoExtractor):
name = "爱奇艺 (Iqiyi)"
stream_types = [
{'id': '4k', 'container': 'f4v', 'video_profile': '4K'},
{'id': 'fullhd', 'container': 'f4v', 'video_profile': '全高清'},
{'id': 'suprt-high', 'container': 'f4v', 'video_profile': '超高清'},
{'id': 'super', 'container': 'f4v', 'video_profile': '超清'},
{'id': 'high', 'container': 'f4v', 'video_profile': '高清'},
{'id': 'standard', 'container': 'f4v', 'video_profile': '标清'},
{'id': 'topspeed', 'container': 'f4v', 'video_profile': '最差'},
]
stream_to_bid = { '4k': 10, 'fullhd' : 5, 'suprt-high' : 4, 'super' : 3, 'high' : 2, 'standard' :1, 'topspeed' :96}
stream_urls = { '4k': [] , 'fullhd' : [], 'suprt-high' : [], 'super' : [], 'high' : [], 'standard' :[], 'topspeed' :[]}
baseurl = ''
gen_uid = ''
def getVMS(self):
#tm ->the flash run time for md5 usage #tm ->the flash run time for md5 usage
#um -> vip 1 normal 0 #um -> vip 1 normal 0
#authkey -> for password protected video ,replace '' with your password #authkey -> for password protected video ,replace '' with your password
#puid user.passportid may empty? #puid user.passportid may empty?
#TODO: support password protected video #TODO: support password protected video
tvid, vid = self.vid
tm, sc, src = mix(tvid) tm, sc, src = mix(tvid)
uid = self.gen_uid
vmsreq='http://cache.video.qiyi.com/vms?key=fvip&src=1702633101b340d8917a69cf8a4b8c7' +\ vmsreq='http://cache.video.qiyi.com/vms?key=fvip&src=1702633101b340d8917a69cf8a4b8c7' +\
"&tvId="+tvid+"&vid="+vid+"&vinfo=1&tm="+tm+\ "&tvId="+tvid+"&vid="+vid+"&vinfo=1&tm="+tm+\
"&enc="+sc+\ "&enc="+sc+\
@ -89,29 +115,23 @@ def getVMS(tvid,vid,uid):
"&authkey="+hashlib.new('md5',bytes(''+str(tm)+tvid,'utf-8')).hexdigest() "&authkey="+hashlib.new('md5',bytes(''+str(tm)+tvid,'utf-8')).hexdigest()
return json.loads(get_content(vmsreq)) return json.loads(get_content(vmsreq))
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()
def iqiyi_download(url, output_dir = '.', merge = True, info_only = False, **kwargs): def prepare(self, **kwargs):
gen_uid=uuid4().hex assert self.url or self.vid
html = get_html(url) if self.url and not self.vid:
html = get_html(self.url)
tvid = r1(r'data-player-tvid="([^"]+)"', html) or r1(r'tvid=([^&]+)', self.url)
videoid = r1(r'data-player-videoid="([^"]+)"', html) or r1(r'vid=([^&]+)', self.url)
self.vid = (tvid, videoid)
tvid = r1(r'data-player-tvid="([^"]+)"', html) or r1(r'tvid=([^&]+)', url) self.gen_uid=uuid4().hex
videoid = r1(r'data-player-videoid="([^"]+)"', html) or r1(r'vid=([^&]+)', url) info = self.getVMS()
assert tvid
assert videoid
info = getVMS(tvid, videoid, gen_uid)
assert info["code"] == "A000000" assert info["code"] == "A000000"
title = info["data"]["vi"]["vn"] self.title = info["data"]["vi"]["vn"]
# data.vp = json.data.vp # data.vp = json.data.vp
# data.vi = json.data.vi # data.vi = json.data.vi
@ -127,38 +147,54 @@ def iqiyi_download(url, output_dir = '.', merge = True, info_only = False, **kwa
log.e("[Error] Do not support for iQIYI VIP video.") log.e("[Error] Do not support for iQIYI VIP video.")
exit(-1) exit(-1)
bid=0 vs = info["data"]["vp"]["tkl"][0]["vs"]
for i in info["data"]["vp"]["tkl"][0]["vs"]: self.baseurl=info["data"]["vp"]["du"].split("/")
if int(i["bid"])<=10 and int(i["bid"])>=bid:
bid=int(i["bid"])
for stream in self.stream_types:
for i in vs:
if self.stream_to_bid[stream['id']] == i['bid']:
video_links=i["fs"] #now in i["flvs"] not in i["fs"] video_links=i["fs"] #now in i["flvs"] not in i["fs"]
if not i["fs"][0]["l"].startswith("/"): if not i["fs"][0]["l"].startswith("/"):
tmp = getVrsEncodeCode(i["fs"][0]["l"]) tmp = getVrsEncodeCode(i["fs"][0]["l"])
if tmp.endswith('mp4'): if tmp.endswith('mp4'):
video_links = i["flvs"] video_links = i["flvs"]
self.stream_urls[stream['id']] = video_links
size = 0
for l in video_links:
size += l['b']
self.streams[stream['id']] = {'container': stream['container'], 'video_profile': stream['video_profile'], 'size' : size}
break
def extract(self, **kwargs):
if 'stream_id' in kwargs and kwargs['stream_id']:
# Extract the stream
stream_id = kwargs['stream_id']
if stream_id not in self.streams:
log.e('[Error] Invalid video format.')
log.e('Run \'-i\' command with no specific video format to view all available formats.')
exit(2)
else:
# Extract stream with the best quality
stream_id = self.streams_sorted[0]['id']
urls=[] urls=[]
size=0 for i in self.stream_urls[stream_id]:
for i in video_links:
vlink=i["l"] vlink=i["l"]
if not vlink.startswith("/"): if not vlink.startswith("/"):
#vlink is encode #vlink is encode
vlink=getVrsEncodeCode(vlink) vlink=getVrsEncodeCode(vlink)
key=getDispathKey(vlink.split("/")[-1].split(".")[0]) key=getDispathKey(vlink.split("/")[-1].split(".")[0])
size+=i["b"] baseurl = [x for x in self.baseurl]
baseurl=info["data"]["vp"]["du"].split("/")
baseurl.insert(-1,key) baseurl.insert(-1,key)
url="/".join(baseurl)+vlink+'?su='+gen_uid+'&qyid='+uuid4().hex+'&client=&z=&bt=&ct=&tn='+str(randint(10000,20000)) url="/".join(baseurl)+vlink+'?su='+self.gen_uid+'&qyid='+uuid4().hex+'&client=&z=&bt=&ct=&tn='+str(randint(10000,20000))
urls.append(json.loads(get_content(url))["l"]) urls.append(json.loads(get_content(url))["l"])
#download should be complete in 10 minutes #download should be complete in 10 minutes
#because the url is generated before start downloading #because the url is generated before start downloading
#and the key may be expired after 10 minutes #and the key may be expired after 10 minutes
print_info(site_info, title, 'flv', size) self.streams[stream_id]['src'] = urls
if not info_only:
download_urls(urls, title, 'flv', size, output_dir = output_dir, merge = merge)
site_info = "iQIYI.com" site = Iqiyi()
download = iqiyi_download download = site.download_by_url
iqiyi_download_by_vid = site.download_by_vid
download_playlist = playlist_not_supported('iqiyi') download_playlist = playlist_not_supported('iqiyi')