mirror of
https://github.com/soimort/you-get.git
synced 2025-01-23 21:45:02 +03:00
rewrit iqiyi using VideoExtractor class
Signed-off-by: Zhang Ning <zhangn1985@gmail.com>
This commit is contained in:
parent
7bdf8af620
commit
5b56b1c8f7
@ -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,90 +73,128 @@ def getVrsEncodeCode(vlink):
|
|||||||
loc2+=chr(loc6)
|
loc2+=chr(loc6)
|
||||||
return loc2[::-1]
|
return loc2[::-1]
|
||||||
|
|
||||||
def getVMS(tvid,vid,uid):
|
|
||||||
#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
|
|
||||||
tm,sc,src = mix(tvid)
|
|
||||||
vmsreq='http://cache.video.qiyi.com/vms?key=fvip&src=1702633101b340d8917a69cf8a4b8c7' +\
|
|
||||||
"&tvId="+tvid+"&vid="+vid+"&vinfo=1&tm="+tm+\
|
|
||||||
"&enc="+sc+\
|
|
||||||
"&qyid="+uid+"&tn="+str(random()) +"&um=1" +\
|
|
||||||
"&authkey="+hashlib.new('md5',bytes(''+str(tm)+tvid,'utf-8')).hexdigest()
|
|
||||||
return json.loads(get_content(vmsreq))
|
|
||||||
|
|
||||||
def getDispathKey(rid):
|
def getDispathKey(rid):
|
||||||
tp=")(*&^flash@#$%a" #magic from swf
|
tp=")(*&^flash@#$%a" #magic from swf
|
||||||
time=json.loads(get_content("http://data.video.qiyi.com/t?tn="+str(random())))["t"]
|
time=json.loads(get_content("http://data.video.qiyi.com/t?tn="+str(random())))["t"]
|
||||||
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()
|
||||||
|
|
||||||
|
class Iqiyi(VideoExtractor):
|
||||||
|
name = "爱奇艺 (Iqiyi)"
|
||||||
|
|
||||||
def iqiyi_download(url, output_dir = '.', merge = True, info_only = False, **kwargs):
|
stream_types = [
|
||||||
gen_uid=uuid4().hex
|
{'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': '最差'},
|
||||||
|
]
|
||||||
|
|
||||||
html = get_html(url)
|
stream_to_bid = { '4k': 10, 'fullhd' : 5, 'suprt-high' : 4, 'super' : 3, 'high' : 2, 'standard' :1, 'topspeed' :96}
|
||||||
|
|
||||||
tvid = r1(r'data-player-tvid="([^"]+)"', html) or r1(r'tvid=([^&]+)', url)
|
stream_urls = { '4k': [] , 'fullhd' : [], 'suprt-high' : [], 'super' : [], 'high' : [], 'standard' :[], 'topspeed' :[]}
|
||||||
videoid = r1(r'data-player-videoid="([^"]+)"', html) or r1(r'vid=([^&]+)', url)
|
|
||||||
|
|
||||||
assert tvid
|
baseurl = ''
|
||||||
assert videoid
|
|
||||||
|
|
||||||
info = getVMS(tvid, videoid, gen_uid)
|
gen_uid = ''
|
||||||
|
def getVMS(self):
|
||||||
assert info["code"] == "A000000"
|
#tm ->the flash run time for md5 usage
|
||||||
|
#um -> vip 1 normal 0
|
||||||
title = info["data"]["vi"]["vn"]
|
#authkey -> for password protected video ,replace '' with your password
|
||||||
|
#puid user.passportid may empty?
|
||||||
# data.vp = json.data.vp
|
#TODO: support password protected video
|
||||||
# data.vi = json.data.vi
|
tvid, vid = self.vid
|
||||||
# data.f4v = json.data.f4v
|
tm, sc, src = mix(tvid)
|
||||||
# if movieIsMember data.vp = json.data.np
|
uid = self.gen_uid
|
||||||
|
vmsreq='http://cache.video.qiyi.com/vms?key=fvip&src=1702633101b340d8917a69cf8a4b8c7' +\
|
||||||
#for highest qualities
|
"&tvId="+tvid+"&vid="+vid+"&vinfo=1&tm="+tm+\
|
||||||
#for http://www.iqiyi.com/v_19rrmmz5yw.html not vp -> np
|
"&enc="+sc+\
|
||||||
try:
|
"&qyid="+uid+"&tn="+str(random()) +"&um=1" +\
|
||||||
if info["data"]['vp']["tkl"]=='' :
|
"&authkey="+hashlib.new('md5',bytes(''+str(tm)+tvid,'utf-8')).hexdigest()
|
||||||
raise ValueError
|
return json.loads(get_content(vmsreq))
|
||||||
except:
|
|
||||||
log.e("[Error] Do not support for iQIYI VIP video.")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
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"])
|
|
||||||
|
|
||||||
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"]
|
|
||||||
|
|
||||||
|
|
||||||
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])
|
|
||||||
size+=i["b"]
|
|
||||||
baseurl=info["data"]["vp"]["du"].split("/")
|
|
||||||
baseurl.insert(-1,key)
|
|
||||||
url="/".join(baseurl)+vlink+'?su='+gen_uid+'&qyid='+uuid4().hex+'&client=&z=&bt=&ct=&tn='+str(randint(10000,20000))
|
|
||||||
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
|
|
||||||
print_info(site_info, title, 'flv', size)
|
|
||||||
if not info_only:
|
|
||||||
download_urls(urls, title, 'flv', size, output_dir = output_dir, merge = merge)
|
|
||||||
|
|
||||||
site_info = "iQIYI.com"
|
def prepare(self, **kwargs):
|
||||||
download = iqiyi_download
|
assert self.url or self.vid
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.gen_uid=uuid4().hex
|
||||||
|
info = self.getVMS()
|
||||||
|
|
||||||
|
assert info["code"] == "A000000"
|
||||||
|
|
||||||
|
self.title = info["data"]["vi"]["vn"]
|
||||||
|
|
||||||
|
# data.vp = json.data.vp
|
||||||
|
# data.vi = json.data.vi
|
||||||
|
# data.f4v = json.data.f4v
|
||||||
|
# if movieIsMember data.vp = json.data.np
|
||||||
|
|
||||||
|
#for highest qualities
|
||||||
|
#for http://www.iqiyi.com/v_19rrmmz5yw.html not vp -> np
|
||||||
|
try:
|
||||||
|
if info["data"]['vp']["tkl"]=='' :
|
||||||
|
raise ValueError
|
||||||
|
except:
|
||||||
|
log.e("[Error] Do not support for iQIYI VIP video.")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
vs = info["data"]["vp"]["tkl"][0]["vs"]
|
||||||
|
self.baseurl=info["data"]["vp"]["du"].split("/")
|
||||||
|
|
||||||
|
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"]
|
||||||
|
if not i["fs"][0]["l"].startswith("/"):
|
||||||
|
tmp = getVrsEncodeCode(i["fs"][0]["l"])
|
||||||
|
if tmp.endswith('mp4'):
|
||||||
|
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=[]
|
||||||
|
for i in self.stream_urls[stream_id]:
|
||||||
|
vlink=i["l"]
|
||||||
|
if not vlink.startswith("/"):
|
||||||
|
#vlink is encode
|
||||||
|
vlink=getVrsEncodeCode(vlink)
|
||||||
|
key=getDispathKey(vlink.split("/")[-1].split(".")[0])
|
||||||
|
baseurl = [x for x in self.baseurl]
|
||||||
|
baseurl.insert(-1,key)
|
||||||
|
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"])
|
||||||
|
#download should be complete in 10 minutes
|
||||||
|
#because the url is generated before start downloading
|
||||||
|
#and the key may be expired after 10 minutes
|
||||||
|
self.streams[stream_id]['src'] = urls
|
||||||
|
|
||||||
|
site = Iqiyi()
|
||||||
|
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')
|
||||||
|
Loading…
Reference in New Issue
Block a user