def prepare(self): info = VideoInfo(self.name, True) if self.url: self.vid = match1(self.url, '/(\d+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, '"room_id.?":(\d+)') info.title = match1(html, '<title>([^<]+)').split('-')[0] if not info.title: info.title = self.name + '-' + str(self.vid) tt = int(time.time() / 60) did = uuid.uuid4().hex.upper() sign_content = '{room_id}{did}A12Svb&%1UUmf@hC{tt}'.format(room_id = self.vid, did = did, tt = tt) sign = hashlib.md5(sign_content.encode('utf-8')).hexdigest() json_request_url = "http://www.douyu.com/lapi/live/getPlay/{}".format(self.vid) for stream in self.stream_ids: payload = {'cdn': 'ws', 'rate': self.stream_id_2_rate[stream], 'tt': tt, 'did': did, 'sign': sign} request_form = urlencode(payload) html_content = get_content(json_request_url, data = compact_bytes(request_form, 'utf-8')) live_data = json.loads(html_content) assert live_data['error'] == 0, '%s: live show is not on line or server error!' % self.name real_url = live_data['data']['rtmp_url'] + '/' + live_data['data']['rtmp_live'] info.stream_types.append(stream) info.streams[stream] = {'container': 'flv', 'video_profile': self.id_2_profile[stream], 'src' : [real_url], 'size': float('inf')} return info
def get_live_info(qn=1): params = { 'https_url_req': 1, 'cid': self.vid, 'platform': 'web', 'qn': qn, 'ptype': '16' } data = json.loads(get_content(api4_url + urlencode(params))) assert data['code'] == 0, data['msg'] data = data['data'] urls = [random.choice(data['durl'])['url']] qlt = data['current_qn'] aqlts = {x['qn']: x['desc'] for x in data['quality_description']} size = float('inf') ext = 'flv' prf = aqlts[qlt] st = self.profile_2_type[prf] if urls and st not in info.streams: info.stream_types.append(st) info.streams[st] = { 'container': ext, 'video_profile': prf, 'src': urls, 'size': size } if qn == 1: del aqlts[qlt] for aqlt in aqlts: get_live_info(aqlt)
def get_live_info(q=0): params = { 'player': 1, 'cid': self.vid, 'platform': 'html5', 'quality': q, 'otype': 'json' } data = json.loads(get_content(api_url + urlencode(params))) assert data['code'] == 0, data['message'] data = data['data'] urls = [random.choice(data['durl'])['url']] qlt = data['current_quality'] aqlts = [int(x) for x in data['accept_quality']] size = float('inf') ext = 'flv' prf = self.supported_stream_profile[4 - qlt] st = self.profile_2_type[prf] if urls and st not in info.streams: info.stream_types.append(st) info.streams[st] = { 'container': ext, 'video_profile': prf, 'src' : urls, 'size': size } if q == 0: aqlts.remove(qlt) for aqlt in aqlts: get_live_info(aqlt)
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) info.title = match1(html, '<title>([^<]+)').split('_')[0] data = json.loads(match1(html, 'channelOneInfo = ({.+?});')) tag_from = 'huomaoh5room' tn = str(int(time.time())) sign_context = data['stream'] + tag_from + tn + SECRETKEY token = hashlib.md5(compact_bytes(sign_context, 'utf-8')).hexdigest() params = { 'streamtype':'live', 'VideoIDS': data['stream'], 'time': tn, 'cdns' : '1', 'from': tag_from, 'token': token } content = get_content(self.live_base, data=compact_bytes(urlencode(params), 'utf-8'), charset='utf-8') stream_data = json.loads(content) assert stream_data["roomStatus"] == "1", "The live stream is not online! " for stream in stream_data["streamList"]: if stream['default'] == 1: defstream = stream['list'] for stream in defstream: info.stream_types.append(stream['type']) info.streams[stream['type']] = {'container': 'flv', 'video_profile': self.stream_2_profile[stream['type']], 'src' : [stream['url']], 'size': float('inf')} info.stream_types = sorted(info.stream_types, key = self.supported_stream_types.index) return info
def get_path_list(self): albumId = match1(self.url, '/a[ab](\d+)') if self.list_only(): html = get_content(self.url) else: html = get_content('https://www.acfun.cn/bangumi/aa' + albumId) groupId = match1(html, '"groups":[{[^}]*?"id":(\d+)') contentsCount = int(match1(html, '"contentsCount":(\d+)')) params = { 'albumId': albumId, 'groupId': groupId, 'num': 1, 'size': max(contentsCount, 20), '_': int(time.time() * 1000), } data = json.loads( get_content('https://www.acfun.cn/album/abm/bangumis/video?' + urlencode(params))) videos = [] for c in data['data']['content']: vid = c['videos'][0]['id'] v = '/bangumi/ab{}_{}_{}'.format(albumId, groupId, vid) videos.append(v) return videos
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) info.title = match1(html, '<title>([^<]+)').split('_')[0] video_name = match1(html, 'getFlash\("[0-9]+","([^"]+)') params = { 'streamtype':'live', 'VideoIDS': video_name, 'cdns' : '1' } form = urlencode(params) content = get_content(self.live_base,data=compact_bytes(form, 'utf-8'),charset = 'utf-8') stream_data = json.loads(content) assert stream_data["roomStatus"] == "1", "The live stream is not online! " for stream in stream_data["streamList"]: if stream['default'] == 1: defstream = stream['list'] for stream in defstream: info.stream_types.append(stream['type']) info.streams[stream['type']] = {'container': 'flv', 'video_profile': self.stream_2_profile[stream['type']], 'src' : [stream['url']], 'size': float('inf')} info.stream_types = sorted(info.stream_types, key = self.supported_stream_types.index) return info
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'song/(\d+)', '\?id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) self.logger.debug("music info >" + str(music)) info.title = music['name'] info.artist = music['artists'][0]['name'] real_id = music["id"] snd_key = random_string() if sys.version_info[0] == 3: encSecKey = RSA_string(snd_key) else: encSecKey = RSA_string(snd_key)[:-1] payload = netease_req(real_id, snd_key, encSecKey) mp3_info = json.loads( get_content(self.mp3_api, data=compact_bytes(urlencode(payload), 'utf-8')))['data'][0] self.logger.debug("mp3 > " + str(mp3_info)) info.stream_types.append('current') info.streams['current'] = { 'container': mp3_info['type'], 'video_profile': 'current', 'src': [mp3_info['url']], 'size': mp3_info['size'] } return info
def prepare(self): info = VideoInfo(self.name) vid, embsig = self.vid params = { 'vid': vid, 'ct': 85, 'ev': 3, 'sign': embsig, 'time': int(time.time() * 1000) } api = 'https://player.acfun.cn/flash_data?' + urlencode(params) rc4_data = json.loads(get_content(api, charset='utf-8'))['data'] data = rc4(self.key, base64.b64decode(rc4_data)) stream_data = json.loads(data) info.title = stream_data['video']['title'] for s in stream_data['stream']: if 'm3u8' in s['stream_type']: continue if 'segs' in s: stream_type = stream_code_to_id[s['stream_type']] stream_urls = [seg['url'] for seg in s['segs']] size = s['total_size'] info.stream_types.append(stream_type) info.streams[stream_type] = { 'container': 'mp4', 'video_profile': stream_code_to_profiles[stream_type], 'src': stream_urls, 'size': size } info.stream_types = sorted(info.stream_types, key=ids.index) return info
def parser_info(self, video, info, stream, lvid, uid): if not 'allot' in info or lvid != info['id']: return stream_id = self.types_2_id[stream] stream_profile = self.id_2_profile[stream_id] host = info['allot'] prot = info['prot'] tvid = info['tvid'] data = info['data'] size = sum(map(int, data['clipsBytes'])) assert len(data['clipsURL']) == len(data['clipsBytes']) == len( data['su']) for new, clip, ck, in zip(data['su'], data['clipsURL'], data['ck']): params = { 'vid': self.vid, 'tvid': tvid, 'file': urlparse(clip).path, 'new': new, 'key': ck, 'uid': uid, 't': random(), 'prod': 'h5', 'prot': prot, 'pt': 1, 'rb': 1, } self.realurls[stream_id].append('https://' + host + '/cdnList?' + urlencode(params)) video.streams[stream_id] = { 'container': 'mp4', 'video_profile': stream_profile, 'size': size } video.stream_types.append(stream_id) self.extract_single(video, stream_id)
def parser_info(self, video, info, stream, lvid, uid): if not 'allot' in info or lvid != info['id']: return stream_id = self.types_2_id[stream] stream_profile = self.id_2_profile[stream_id] host = info['allot'] prot = info['prot'] tvid = info['tvid'] data = info['data'] size = sum(map(int,data['clipsBytes'])) urls = [] assert len(data['clipsURL']) == len(data['clipsBytes']) == len(data['su']) for new, clip, ck, in zip(data['su'], data['clipsURL'], data['ck']): params = { 'vid': self.vid, 'tvid': tvid, 'file': urlparse(clip).path, 'new': new, 'key': ck, 'uid': uid, 't': random(), 'prod': 'h5', 'prot': prot, 'pt': 1, 'rb': 1, } if urlparse(new).netloc == '': cdnurl = 'https://'+host+'/cdnList?' + urlencode(params) url = json.loads(get_content(cdnurl))['url'] else: url = new urls.append(url) video.streams[stream_id] = {'container': 'mp4', 'video_profile': stream_profile, 'src': urls, 'size' : size} video.stream_types.append(stream_id)
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) info.title = match1(html, '<title>([^<]+)').split('_')[0] video_name = match1(html, '"stream":"([^"]+)') params = {'streamtype': 'live', 'VideoIDS': video_name, 'cdns': '1'} form = urlencode(params) content = get_content(self.live_base, data=compact_bytes(form, 'utf-8'), charset='utf-8') stream_data = json.loads(content) assert stream_data[ "roomStatus"] == "1", "The live stream is not online! " for stream in stream_data["streamList"]: if stream['default'] == 1: defstream = stream['list'] for stream in defstream: info.stream_types.append(stream['type']) info.streams[stream['type']] = { 'container': 'flv', 'video_profile': self.stream_2_profile[stream['type']], 'src': [stream['url']], 'size': float('inf') } info.stream_types = sorted(info.stream_types, key=self.supported_stream_types.index) return info
def getlive(vid): tm = time.time() host = 'https://live.video.iqiyi.com' params = { 'lp': vid, 'src': '01010031010000000000', 'uid': '', 'rateVers': 'PC_QIYI_3', 'k_uid': get_macid(24), 'qdx': 'n', 'qdv': 3, 'qd_v': 1, 'dfp': get_random_str(66), 'v': 1, 'k_err_retries': 0, 'tm': int(tm + 1), } src = '/live?{}'.format(urlencode(params)) vf = cmd5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) st = int(tm * 1000) et = int((tm + 1296000) * 1000) c_dfp = '__dfp={}@{}@{}'.format(params['dfp'], et, st) add_header('Cookie', c_dfp) html = get_content(req_url) return json.loads(html)
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: html = get_content(self.url) room = match1(html, 'var $ROOM = ([^;]+)') self.vid = match1(html, '"room_id.?":(\d+)') info.title = json.loads("{\"room_name\" : \"" + match1(html, '"room_name.?":"([^"]+)') + "\"}")['room_name'] info.artist = json.loads("{\"name\" : \"" + match1(html, '"owner_name.?":"([^"]+)') + "\"}")['name'] api_url = 'https://www.douyu.com/lapi/live/getPlay/{}'.format(self.vid) tt = str(int(time.time() / 60)) rnd_md5 = hashlib.md5(str(random.random()).encode('utf8')) did = rnd_md5.hexdigest().upper() to_sign = ''.join([self.vid, did, API_KEY, tt]) sign = stupidMD5(to_sign) for stream in self.stream_ids: rate = self.stream_id_2_rate[stream] params = {"ver" : VER, "sign" : sign, "did" : did, "rate" : rate, "tt" : tt, "cdn" : "ws"} form = urlencode(params) html_content = get_content(api_url, data=compact_bytes(form, 'utf-8')) live_data = json.loads(html_content) assert live_data["error"] == 0, "live show is offline" live_data = live_data["data"] real_url = '/'.join([live_data['rtmp_url'], live_data['rtmp_live']]) info.stream_types.append(stream) info.streams[stream] = {'container': 'flv', 'video_profile': self.id_2_profile[stream], 'src' : [real_url], 'size': float('inf')} return info
def qq_get_final_url(url, fmt_name, type_name, br, form, fn): content = get_content('http://vv.video.qq.com/getkey',data=compact_bytes(form, 'utf-8'), charset = 'ignore') tree = ET.fromstring(content) vkey = tree.find('./key') if vkey is None: return else: vkey = vkey.text level = tree.find('./level').text sp = tree.find('./sp').text params = { 'stdfrom': 'v1090', 'type': type_name, 'vkey': vkey, 'level': level, 'platform': PLAYER_PLATFORM, 'br': br, 'fmt': fmt_name, 'sp': sp, } form = urlencode(params) return "%s?%s" % (url, form)
def parser_info(self, video, info, stream, lvid, uid): if not 'allot' in info or lvid != info['id']: return stream_id = self.types_2_id[stream] stream_profile = self.id_2_profile[stream_id] host = info['allot'] prot = info['prot'] tvid = info['tvid'] data = info['data'] size = sum(map(int,data['clipsBytes'])) urls = [] assert len(data['clipsURL']) == len(data['clipsBytes']) == len(data['su']) for new, clip, ck, in zip(data['su'], data['clipsURL'], data['ck']): params = { 'vid': self.vid, 'tvid': tvid, 'file': urlparse(clip).path, 'new': new, 'key': ck, 'uid': uid, 't': random(), 'prod': 'h5', 'prot': prot, 'pt': 1, 'rb': 1, } if urlparse(new).netloc == '': cdnurl = 'https://'+host+'/cdnList?' + urlencode(params) url = json.loads(get_content(cdnurl))['url'] else: url = new urls.append(url) video.streams[stream_id] = {'container': 'mp4', 'video_profile': stream_profile, 'src': urls, 'size' : size} video.stream_types.append(stream_id)
def prepare(self): info = VideoInfo(self.name) add_header("Referer", "http://music.163.com/") if not self.vid: self.vid = match1(self.url, 'song/(\d+)', '\?id=(.*)') api_url = self.api_url.format(self.vid, self.vid) music = self.get_music(json.loads(get_content(api_url))) self.logger.debug("music info >" + str(music)) info.title = music['name'] info.artist = music['artists'][0]['name'] real_id = music["id"] snd_key = random_string() if sys.version_info[0] == 3: encSecKey = RSA_string(snd_key) else: encSecKey = RSA_string(snd_key)[:-1] payload = netease_req(real_id, snd_key, encSecKey) mp3_info = json.loads(get_content(self.mp3_api, data=compact_bytes(urlencode(payload), 'utf-8')))['data'][0] self.logger.debug("mp3 > " + str(mp3_info)) info.stream_types.append('current') info.streams['current'] = {'container': mp3_info['type'], 'video_profile': 'current', 'src' : [mp3_info['url']], 'size': mp3_info['size']} return info
def getlive(vid): tm = time.time() host = 'https://live.video.iqiyi.com' params = { 'lp': vid, 'src': '01010031010000000000', 'uid': '', 'rateVers': 'PC_QIYI_3', 'k_uid': get_macid(24), 'qdx': 'n', 'qdv': 3, 'qd_v': 1, 'dfp': get_random_str(66), 'v': 1, 'k_err_retries': 0, 'tm': int(tm + 1), } src = '/live?{}'.format(urlencode(params)) vf = cmd5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) st = int(tm * 1000) et = int((tm + 1296000) * 1000) c_dfp = '__dfp={}@{}@{}'.format(params['dfp'], et, st) add_header('Cookie', c_dfp) html = get_content(req_url) return json.loads(html)
def parser_info(self, video, info, stream, lvid, uid): if not 'allot' in info or lvid != info['id']: return stream_id = self.types_2_id[stream] stream_profile = self.id_2_profile[stream_id] host = info['allot'] data = info['data'] size = sum(map(int, data['clipsBytes'])) urls = [] assert len(data['clipsURL']) == len(data['clipsBytes']) == len( data['su']) for new, ck, in zip(data['su'], data['ck']): params = { 'ch': data['ch'], 'num': data['num'], 'new': new, 'key': ck, 'uid': uid, 'prod': 'h5n', 'pt': 1, 'pg': 2, } if urlparse(new).netloc == '': cdnurl = 'https://{}/ip?{}'.format(host, urlencode(params)) url = json.loads(get_content(cdnurl))['servers'][0]['url'] else: url = new urls.append(url) video.streams[stream_id] = { 'container': 'mp4', 'video_profile': stream_profile, 'src': urls, 'size': size } video.stream_types.append(stream_id)
def prepare(self): if self.url and not self.vid: self.vid = match1(self.url, '\Wvid=(\d+)', '\Wid=(\d+)', '\Wbid=(\d+)', 'share_play.html#(\d+)_') if not self.vid: html = get_content(self.url) self.vid = match1(html, '/(\d+)/v\.swf', 'vid="(\d+)"', '\&id=(\d+)') self.logger.debug("VID> {}".format(self.vid)) info = json.loads(get_content(self.apiurl % self.vid)) self.logger.debug("info> {}".format(info)) if info['status'] == 6: self.name = u'搜狐自媒体 (MySohu)' self.apiurl = 'http://my.tv.sohu.com/play/videonew.do?vid=%s&referer=http://my.tv.sohu.com' info = json.loads(get_content(self.apiurl % self.vid)) self.logger.debug("info> {}".format(info)) video = VideoInfo(self.name) # this is needless now, uid well be registered in the the following code #video.extra["header"] = "Range: " if info['status'] == 1: now = time.time() uid = int(now * 1000) params = { 'vid': self.vid, 'url': self.url, 'refer': self.url, 't': int(now), 'uid': uid, #'nid': nid, #'pid': pid, #'screen': '1366x768', #'channeled': channeled, #'MTV_SRC': MTV_SRC, #'position': 'page_adbanner', #'op': 'click', #'details': '{}', #'os': 'linux', #'platform': 'linux', #'passport': '', } get_content('http://z.m.tv.sohu.com/h5_cc.gif?' + urlencode(params)) data = info['data'] video.title = data['tvName'] for stream in self.supported_stream_types: lvid = data.get(stream) if lvid == 0 or not lvid: continue if lvid != self.vid: _info = json.loads(get_content(self.apiurl % lvid)) self.logger.debug("info> {}".format(_info)) else: _info = info self.parser_info(video, _info, stream, lvid, uid) return video
def get_api_url(self, qn): params_str = urlencode({ 'appkey': APPKEY, 'cid': self.vid, 'platform': 'html5', 'player': 0, 'qn': qn }) return sign_api_url(api_url, params_str, SECRETKEY)
def get_api_url(self, qn): params_str = urlencode([ ('appkey', APPKEY), ('cid', self.vid), ('platform', 'html5'), ('player', 0), ('qn', qn) ]) return sign_api_url(api_url, params_str, SECRETKEY)
def prepare(self): if self.url and not self.vid: self.vid = match1(self.url, '\Wvid=(\d+)', '\Wid=(\d+)', 'share_play.html#(\d+)_') if not self.vid: html = get_content(self.url) self.vid = match1(html, '/(\d+)/v\.swf', 'vid="(\d+)"', '\&id=(\d+)') self.logger.debug("VID> {}".format(self.vid)) info = json.loads(get_content(self.apiurl % self.vid)) self.logger.debug("info> {}".format(info)) if info['status'] == 6: self.name = u'搜狐自媒体 (MySohu)' self.apiurl = 'http://my.tv.sohu.com/play/videonew.do?vid=%s&referer=http://my.tv.sohu.com' info = json.loads(get_content(self.apiurl % self.vid)) self.logger.debug("info> {}".format(info)) video = VideoInfo(self.name) # this is needless now, uid well be registered in the the following code #video.extra["header"] = "Range: " if info['status'] == 1: now = time.time() uid = int(now * 1000) params = { 'vid': self.vid, 'url': self.url, 'refer': self.url, 't': int(now), 'uid': uid, #'nid': nid, #'pid': pid, #'screen': '1366x768', #'channeled': channeled, #'MTV_SRC': MTV_SRC, #'position': 'page_adbanner', #'op': 'click', #'details': '{}', #'os': 'linux', #'platform': 'linux', #'passport': '', } get_content('http://z.m.tv.sohu.com/h5_cc.gif?' + urlencode(params)) data = info['data'] video.title = data['tvName'] for stream in self.supported_stream_types: lvid = data.get(stream) if lvid == 0 or not lvid: continue if lvid != self.vid: _info = json.loads(get_content(self.apiurl % lvid)) self.logger.debug("info> {}".format(_info)) else: _info = info self.parser_info(video, _info, stream, lvid, uid) return video
def get_api_url(self, qn): params_str = urlencode({ 'appkey': APPKEY, 'cid': self.vid, 'module': 'bangumi', 'platform': 'html5', 'player': 1, 'qn': qn, 'season_type': self.seasonType }) return sign_api_url(api_url, params_str, SECRETKEY)
def prepare(self): if not self.vid: self.vid = match1(self.url, 'sid=(\d+)') params = { "source" : "", "sids" : self.vid, "ck" : "" } form = urlencode(params) data = json.loads(get_content('https://music.douban.com/j/artist/playlist', data = compact_bytes(form, 'utf-8'))) self.song_info = data['songs'][0]
def prepare(self): info = VideoInfo(self.name) self.vid = match1(self.url, 'play/(\d+)') html = get_content(self.url) if not self.vid: self.vid = match1(html, 'data-vid="(\d+)') title = match1(html, '<h1 class="video-title">(.+?)</h1>') info.artist = artist = match1( html, "<div class='video-author'>[\s\S]+?<h3>(.+?)</h3>") info.title = u'{} - {}'.format(title, artist) t1 = int(time.time() * 1000) t2 = t1 + random.randrange(5, 10) rnd = str(random.random()).replace('.', '') params = { 'callback': 'jQuery1124{}_{}'.format(rnd, t1), 'r': 'vhuyaplay/video', 'vid': self.vid, 'format': 'mp4,m3u8', '_': t2 } api_url = 'https://v-api-player-ssl.huya.com/?' + urlencode(params) data = get_content(api_url)[len(params['callback']) + 1:-1] self.logger.debug('data:\n%s', data) data = json.loads(data) assert data['code'] == 1, data['message'] data = data['result']['items'] for stream_date in data: ext = stream_date['format'] quality = min( int(q) for q in (stream_date['height'], stream_date['width'])) stream = self.quality_2_id[quality] if stream not in info.stream_types: info.stream_types.append(stream) elif ext == 'm3u8': # prefer mp4 continue video_profile = self.id_2_profile[stream] url = stream_date['transcode']['urls'][0] info.streams[stream] = { 'container': ext, 'video_profile': video_profile, 'src': [url], 'size': int(stream_date['size']) } info.stream_types = sorted(info.stream_types, key=self.supported_stream_types.index) return info
def gettmts(tvid, vid): tm = int(time.time() * 1000) key = 'd5fb4bd9d50c4be6948c97edd7254b0e' host = 'https://cache.m.iqiyi.com' params = { 'src': '76f90cbd92f94a2e925d83e8ccd22cb7', 'sc': md5(str(tm) + key + vid), 't': tm } src = '/tmts/{}/{}/?{}'.format(tvid, vid, urlencode(params)) req_url = '{}{}'.format(host, src) html = get_content(req_url) return json.loads(html)
def gettmts(tvid, vid): tm = int(time.time() * 1000) key = 'd5fb4bd9d50c4be6948c97edd7254b0e' host = 'https://cache.m.iqiyi.com' params = { 'src': '76f90cbd92f94a2e925d83e8ccd22cb7', 'sc': md5(str(tm) + key + vid), 't': tm } src = '/tmts/{}/{}/?{}'.format(tvid, vid, urlencode(params)) req_url = '{}{}'.format(host, src) html = get_content(req_url) return json.loads(html)
def prepare(self): if not self.vid: self.vid = match1(self.url, 'http://music.baidu.com/song/([\d]+)') param = urlencode({'songIds': self.vid}) song_data = json.loads(get_content('http://play.baidu.com/data/music/songlink', data=compact_bytes(param, 'utf-8')))['data']['songList'][0] self.title = song_data['songName'] self.artist = song_data['artistName'] self.stream_types.append('current') self.streams['current'] = {'container': song_data['format'], 'video_profile': 'current', 'src' : [song_data['songLink']], 'size': song_data['size']}
def download_playlist(self, url, param): self.param = param sids = match1(url, 'sid=([0-9,]+)') params = { "source" : "", "sids" : sids, "ck" : "" } form = urlencode(params) data = json.loads(get_content('https://music.douban.com/j/artist/playlist', data = compact_bytes(form, 'utf-8'))) for s in data['songs']: self.song_info = s self.download_normal()
def prepare(self): info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url, 'sid=(\d+)') params = { "source" : "", "sids" : self.vid, "ck" : "" } form = urlencode(params) data = json.loads(get_content('https://music.douban.com/j/artist/playlist', data = compact_bytes(form, 'utf-8'))) self.song_info = data['songs'][0] self.extract_song(info) return info
def getdash(tvid, vid, bid=500): tm = int(time.time() * 1000) host = 'https://cache.video.iqiyi.com' params = { #'uid': '', 'k_uid': get_macid(), # necessary #'dfp': dfp, #'pck': '', #'bop': '{{"version":"10.0","dfp":"{dfp}"}}'.format(dfp=dfp), # keys above are relative to cookies 'tvid': tvid, 'bid': bid, 'vid': vid, 'src': '01010031010000000000', 'vt': 0, 'rs': 1, 'ori': 'pcw', 'ps': 1, 'pt': 0, 'd': 0, 's': '', 'lid': '', 'cf': '', 'ct': '', 'authKey': cmd5x('{}{}{}'.format(cmd5x(''), tm, tvid)), 'k_tag': 1, 'ost': 0, 'ppt': 0, 'locale': 'zh_cn', 'prio': '{"ff":"f4v","code":2}', 'k_err_retries': 0, 'up': '', 'qd_v': 2, 'tm': tm, 'qdy': 'a', 'qds': 0, 'ut': 0, # 600 bid isn't available # relative to encode #'k_ft1': , #'k_ft4': , #'k_ft5': , } src = '/dash?{}'.format(urlencode(params)) vf = cmd5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) html = get_content(req_url) return json.loads(html)
def parser_list(self, url): sids = match1(url, 'sid=([0-9,]+)') params = {"source": "", "sids": sids, "ck": ""} form = urlencode(params) data = json.loads( get_content('https://music.douban.com/j/artist/playlist', data=compact_bytes(form, 'utf-8'))) info_list = [] for s in data['songs']: info = VideoInfo(self.name) self.song_info = s self.extract_song(info) info_list.append(info) return info_list
def get_live_info(rate=0): params['rate'] = rate data = urlencode(params) if not isinstance(data, bytes): data = data.encode() html_content = get_content( 'https://www.douyu.com/lapi/live/getH5Play/{}'.format( self.vid), data=data) self.logger.debug(html_content) live_data = json.loads(html_content) if live_data['error']: return live_data['msg'] live_data = live_data["data"] real_url = '{}/{}'.format(live_data['rtmp_url'], live_data['rtmp_live']) rate_2_profile = dict((rate['rate'], rate['name']) for rate in live_data['multirates']) video_profile = rate_2_profile[live_data['rate']] if '原画' in video_profile: stream = 'OG' else: stream = self.profile_2_id[video_profile] if stream in info.streams: return info.stream_types.append(stream) info.streams[stream] = { 'container': match1(live_data['rtmp_live'], '\.(\w+)\?'), 'video_profile': video_profile, 'src': [real_url], 'size': float('inf') } error_msges = [] if rate == 0: rate_2_profile.pop(0, None) rate_2_profile.pop(live_data['rate'], None) for rate in rate_2_profile: error_msg = get_live_info(rate) if error_msg: error_msges.append(error_msg) if error_msges: return ', '.join(error_msges)
def qq_get_final_url(url, vid, fmt_id, filename, fvkey): params = { 'appver': PLAYER_VERSION, 'otype': 'json', 'platform': PLAYER_PLATFORM, 'filename': filename, 'vid': vid, 'format': fmt_id, } content = get_content('http://vv.video.qq.com/getkey?' + urlencode(params)) data = json.loads(match1(content, r'QZOutputJson=(.+);$')) vkey = data.get('key') if vkey is None: vkey = fvkey return "{}{}?vkey={}".format(url, filename, vkey)
def prepare(self): info = VideoInfo(self.name) pid = match1(self.url, 'show/(.*)') if 'vmobile' in self.url: self.url = 'https://v.douyu.com/show/' + pid html = get_content(self.url) info.title = match1(html, u'title>(.+?)_斗鱼视频 - 最6的弹幕视频网站<') self.vid = match1(html, '"point_id":\s?(\d+)') js_enc = get_h5enc(html, self.vid) params = {'vid': pid} ub98484234(js_enc, self, params) add_header("Referer", self.url) add_header('Cookie', 'dy_did={}'.format(params['did'])) data = urlencode(params) if not isinstance(data, bytes): data = data.encode() html_content = get_content( 'https://v.douyu.com/api/stream/getStreamUrl', data=data) self.logger.debug('video_data: ' + html_content) video_data = json.loads(html_content) assert video_data['error'] == 0, video_data for video_profile, stream_date in video_data['data'][ 'thumb_video'].items(): if not stream_date: continue stream = self.profile_2_id[video_profile] info.stream_types.append(stream) info.streams[stream] = { 'container': 'm3u8', 'video_profile': video_profile, 'src': [stream_date['url']], 'size': 0 } info.stream_types = sorted(info.stream_types, key=self.stream_ids.index) return info
def getvps(tvid, vid): tm = int(time.time() * 1000) host = 'http://cache.video.qiyi.com' params = { 'tvid': tvid, 'vid': vid, 'v': 0, 'qypid': '{}_12'.format(tvid), 'src': '01012001010000000000', 't': tm, 'k_tag': 1, 'k_uid': get_macid(), 'rs': 1, } src = '/vps?{}'.format(urlencode(params)) vf = md5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) html = get_content(req_url) return json.loads(html)
def parser_list(self, url): sids = match1(url, 'sid=([0-9,]+)') params = { "source" : "", "sids" : sids, "ck" : "" } form = urlencode(params) data = json.loads(get_content('https://music.douban.com/j/artist/playlist', data = compact_bytes(form, 'utf-8'))) info_list = [] for s in data['songs']: info = VideoInfo(self.name) self.song_info = s self.extract_song(info) info_list.append(info) return info_list
def getvps(tvid, vid): tm = int(time.time() * 1000) host = 'http://cache.video.qiyi.com' params = { 'tvid': tvid, 'vid': vid, 'v': 0, 'qypid': '{}_12'.format(tvid), 'src': '01012001010000000000', 't': tm, 'k_tag': 1, 'k_uid': get_macid(), 'rs': 1, } src = '/vps?{}'.format(urlencode(params)) vf = md5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) html = get_content(req_url) return json.loads(html)
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) info.title = match1(html, '<title>([^<]+)').split('_')[0] data = json.loads(match1(html, 'channelOneInfo = ({.+?});')) tag_from = 'huomaoh5room' tn = str(int(time.time())) sign_context = data['stream'] + tag_from + tn + SECRETKEY token = hashlib.md5(compact_bytes(sign_context, 'utf-8')).hexdigest() params = { 'streamtype': 'live', 'VideoIDS': data['stream'], 'time': tn, 'cdns': '1', 'from': tag_from, 'token': token } content = get_content(self.live_base, data=compact_bytes(urlencode(params), 'utf-8'), charset='utf-8') stream_data = json.loads(content) assert stream_data[ "roomStatus"] == "1", "The live stream is not online! " for stream in stream_data["streamList"]: if stream['default'] == 1: defstream = stream['list'] for stream in defstream: info.stream_types.append(stream['type']) info.streams[stream['type']] = { 'container': 'flv', 'video_profile': self.stream_2_profile[stream['type']], 'src': [stream['url']], 'size': float('inf') } info.stream_types = sorted(info.stream_types, key=self.supported_stream_types.index) return info
def extract_single(self, stream_id): sid, token = init(self.ep) segs = self.streams_parameter[stream_id]['segs'] streamfileid = self.streams_parameter[stream_id]['fileid'] urls = [] no = 0 for seg in segs: k = seg['key'] assert k != -1 fileId = getFileid(streamfileid, no) ep = create_ep(sid, fileId, token) q = urlencode(dict( ctype = self.ct, ev = 1, K = k, ep = ep, oip = str(self.ip), token = token, yxon = 1, myp = 0, ymovie= 1, ts = seg['total_milliseconds_audio'][:-3], hd = stream_type_to_hd[stream_code_to_type[stream_id]], special = 'true', yyp = 2 )) nu = '%02x' % no u = 'http://k.youku.com/player/getFlvPath/sid/{sid}_{nu}' \ '/st/{container}/fileid/{fileid}?{q}'.format( sid = sid, nu = nu, container = self.streams[stream_id]['container'], fileid = fileId, q = q ) no += 1 url = json.loads(get_content(u))[0]['server'] urls.append(url) self.streams[stream_id]['src'] = urls if not self.streams[stream_id]['src'] and self.password_protected: log.e('[Failed] Wrong password.')
def extract_single(self, info, stream_id): sid, token = init(self.ep) segs = self.streams_parameter[stream_id]['segs'] streamfileid = self.streams_parameter[stream_id]['fileid'] urls = [] no = 0 for seg in segs: k = seg['key'] assert k != -1, '%s invalid segment key!' % self.name fileId = getFileid(streamfileid, no) ep = create_ep(sid, fileId, token) q = urlencode(dict( ctype = self.ct, ev = 1, K = k, ep = ep, oip = str(self.ip), token = token, yxon = 1, myp = 0, ymovie= 1, ts = seg['total_milliseconds_audio'][:-3], hd = stream_type_to_hd[stream_id], special = 'true', yyp = 2 )) nu = '%02x' % no u = 'http://k.youku.com/player/getFlvPath/sid/{sid}_{nu}' \ '/st/{container}/fileid/{fileid}?{q}'.format( sid = sid, nu = nu, container = info.streams[stream_id]['container'], fileid = fileId, q = q ) no += 1 url = json.loads(get_content(u))[0]['server'] urls.append(url) info.streams[stream_id]['src'] = urls if not info.streams[stream_id]['src'] and self.password_protected: log.e('[Failed] Wrong password.')
def qq_get_final_url(url, fmt_name, type_name, br, form, fn): content = get_content('http://vv.video.qq.com/getkey',data=compact_bytes(form, 'utf-8'), charset = 'ignore') tree = ET.fromstring(content) vkey = tree.find('./key').text level = tree.find('./level').text sp = tree.find('./sp').text params = { 'stdfrom': 'v1090', 'type': type_name, 'vkey': vkey, 'level': level, 'platform': PLAYER_PLATFORM, 'br': br, 'fmt': fmt_name, 'sp': sp, } form = urlencode(params) return "%s?%s" % (url, form)
def qq_get_final_url(url, vid, fmt_id, filename, fvkey, platform): params = { 'appver': PLAYER_VERSION, 'otype': 'json', 'platform': platform, 'filename': filename, 'vid': vid, 'format': fmt_id, } content = get_content('http://vv.video.qq.com/getkey?' + urlencode(params)) data = json.loads(match1(content, r'QZOutputJson=(.+);$')) vkey = data.get('key', fvkey) if vkey: url = "{}{}?vkey={}".format(url, filename, vkey) else: url = None vip = data.get('msg') == 'not pay' return url, vip
def qq_get_final_url(url, vid, fmt_id, filename, fvkey, platform): params = { 'appver': PLAYER_VERSION, 'otype': 'json', 'platform': platform, 'filename': filename, 'vid': vid, 'format': fmt_id, } content = get_content('http://vv.video.qq.com/getkey?' + urlencode(params)) data = json.loads(match1(content, r'QZOutputJson=(.+);$')) vkey = data.get('key', fvkey) if vkey: url = '{}{}?vkey={}'.format(url, filename, vkey) else: url = None vip = data.get('msg') == 'not pay' return url, vip
def getlive(uid, rate='source'): tm = int(time.time()) api = 'https://m-glider-xiu.pps.tv/v2/stream/get.json' params = { 'type_id': 1, 'vid': 1, 'anchor_id': uid, 'app_key': 'show_web_h5', 'version': '1.0.0', 'platform': '1_10_101', 'time': tm, 'netstat': 'wifi', 'device_id': get_macid(), 'bit_rate_type': rate, 'protocol': 5, } params['sign'] = gsign(params) data = urlencode(params) if not isinstance(data, bytes): data = data.encode() html = get_content(api, data=data) return json.loads(html)
def get_live_info(rate=0): params['rate'] = rate data = urlencode(params) if not isinstance(data, bytes): data = data.encode() html_content = get_content('https://www.douyu.com/lapi/live/getH5Play/{}'.format(self.vid), data=data) self.logger.debug(html_content) live_data = json.loads(html_content) if live_data['error']: return live_data['msg'] live_data = live_data["data"] real_url = '{}/{}'.format(live_data['rtmp_url'], live_data['rtmp_live']) rate_2_profile = dict((rate['rate'], rate['name']) for rate in live_data['multirates']) video_profile = rate_2_profile[live_data['rate']] stream = self.profile_2_id[video_profile] if stream in info.streams: return info.stream_types.append(stream) info.streams[stream] = { 'container': 'flv', 'video_profile': video_profile, 'src' : [real_url], 'size': float('inf') } error_msges = [] if rate == 0: rate_2_profile.pop(0, None) rate_2_profile.pop(live_data['rate'], None) for rate in rate_2_profile: error_msg = get_live_info(rate) if error_msg: error_msges.append(error_msg) if error_msges: return ', '.join(error_msges)
def getdash(tvid, vid, bid=500): tm = int(time.time() * 1000) host = 'https://cache.video.iqiyi.com' params = { 'tvid': tvid, 'bid': bid, 'vid': vid, 'src': '01010031010000000000', 'vt': 0, 'rs': 1, 'uid': '', 'ori': 'pcw', 'ps': 0, 'tm': tm, 'qd_v': 1, 'k_uid': get_macid(), 'pt': 0, 'd': 0, 's': '', 'lid': '', 'cf': '', 'ct': '', 'authKey': cmd5x('0{}{}'.format(tm, tvid)), 'k_tag': 1, 'ost': 0, 'ppt': 0, 'locale': 'zh_cn', 'pck': '', 'k_err_retries': 0, 'ut': 0 } src = '/dash?{}'.format(urlencode(params)) vf = cmd5x(src) req_url = '{}{}&vf={}'.format(host, src, vf) html = get_content(req_url) return json.loads(html)
def prepare(self): add_header("Cookie", '__ysuid=%d' % time.time()) info = VideoInfo(self.name) if not self.vid: self.vid = match1(self.url.split('//', 1)[1], '^v[^\.]?\.[^/]+/v_show/id_([a-zA-Z0-9=]+)', '^player[^/]+/(?:player\.php/sid|embed)/([a-zA-Z0-9=]+)', '^static.+loader\.swf\?VideoIDS=([a-zA-Z0-9=]+)', '^(?:new-play|video)\.tudou\.com/v/([a-zA-Z0-9=]+)') if not self.vid: html = get_content(self.url) self.vid = match1(html, r'videoIds?[\"\']?\s*[:=]\s*[\"\']?([a-zA-Z0-9=]+)') if self.vid.isdigit(): import base64 vid = base64.b64encode(b'%d' % (int(self.vid) * 4)) if not isinstance(vid, str): vid = vid.decode() self.vid = 'X' + vid self.logger.debug("VID: " + self.vid) utid = fetch_cna() for ccode, ref, ckey in self.params: add_header("Referer", ref) if len(ccode) > 4: _utid = generateUtdid() else: _utid = utid params = { 'vid': self.vid, 'ccode': ccode, 'utid': _utid, 'ckey': ckey, 'client_ip': '192.168.1.1', 'client_ts': int(time.time()), } data = None while data is None: e1 = 0 e2 = 0 data = json.loads(get_content('https://ups.youku.com/ups/get.json?' + urlencode(params))) self.logger.debug("data: " + str(data)) e1 = data['e']['code'] e2 = data['data'].get('error') if e2: e2 = e2['code'] if e1 == 0 and e2 in (-2002, -2003): from getpass import getpass data = None if e2 == -2002: self.logger.warning('This video has protected!') elif e2 == -2003: self.logger.warning('Your password [{}] is wrong!'.format(params['password'])) params['password'] = getpass('Input password:'******'e']['desc'] data = data['data'] assert 'stream' in data, data['error']['note'] info.title = data['video']['title'] audio_lang = 'default' if 'dvd' in data and 'audiolang' in data['dvd']: for l in data['dvd']["audiolang"]: if l['vid'].startswith(self.vid): audio_lang = l['langcode'] break streams = data['stream'] for s in streams: if not audio_lang == s['audio_lang']: continue self.logger.debug("stream> " + str(s)) t = stream_code_to_id[s['stream_type']] urls = [] for u in s['segs']: self.logger.debug("seg> " + str(u)) if u['key'] != -1: if 'cdn_url' in u: urls.append(u['cdn_url']) else: self.logger.warning("VIP video, ignore unavailable seg: {}".format(s['segs'].index(u))) if len(urls) == 0: urls = [s['m3u8_url']] c = 'm3u8' else: c = id_to_container[t] size = s['size'] info.stream_types.append(t) info.streams[t] = { 'container': c, 'video_profile': stream_code_to_profiles[t], 'size': size, 'src' : urls } info.stream_types = sorted(info.stream_types, key = ids.index) tmp = [] for t in info.stream_types: if not t in tmp: tmp.append(t) info.stream_types = tmp return info
def get_stream_info(self, profile): player_pid = uuid.uuid4().hex.upper() params = { 'fp2p': 1, 'pid': player_pid, 'otype': 'xml', 'defn': profile, 'platform': 1, 'fhdswitch': 0, 'charge': 0, 'ckey' : "", 'vid': self.vid, 'defnpayver': 1, 'encryptVer': "", 'speed': random.randint(512, 1024), 'ran': random.random(), 'appver': PLAYER_VERSION, 'defaultfmt': profile, 'utype': -1, 'vids': self.vid } form = urlencode(params) content = get_content('http://vv.video.qq.com/getinfo',data=compact_bytes(form, 'utf-8'), charset = 'ignore') tree = ET.fromstring(content) fmt_id = None fmt_name = None fmt_br = None for fmt in tree.findall('./fl/fi'): sl = int(fmt.find('./sl').text) if sl: fmt_id = fmt.find('./id').text fmt_name = fmt.find('./name').text fmt_br = fmt.find('./br').text video = tree.find('./vl/vi') filename = video.find('./fn').text title = video.find('./ti').text cdn = video.find('./ul/ui') cdn_url = cdn.find('./url').text filetype = int(cdn.find('./dt').text) vt = cdn.find('./vt').text if filetype == 1: type_name = 'flv' elif filetype == 2: type_name = 'mp4' else: type_name = 'unknown' num_clips = len(video.findall('./cl/ci')) size = int(video.find('./fs').text) fns = os.path.splitext(filename) #may have preformence issue when info_only urls =[] if num_clips == 0: params = { 'ran': random.random(), 'appver': PLAYER_VERSION, 'otype': 'xml', 'encryptVer': "", 'platform': 1, 'filename': filename, 'vid': self.vid, 'vt': vt, 'charge': 0, 'format': fmt_id, 'cKey': "", } form = urlencode(params) clip_url = '%s%s' % (cdn_url, filename) urls.append(qq_get_final_url(clip_url, fmt_name, type_name, fmt_br, form, filename)) else: for idx in range(1, num_clips+1): fn = '%s.%d%s' % (fns[0], idx, fns[1]) params = { 'ran': random.random(), 'appver': PLAYER_VERSION, 'otype': 'xml', 'encryptVer': "", 'platform': 1, 'filename': fn, 'vid': self.vid, 'vt': vt, 'charge': 0, 'format': fmt_id, 'cKey': "", } form = urlencode(params) clip_url = '%s%s' % (cdn_url, fn) urls.append(qq_get_final_url(clip_url, fmt_name, type_name, fmt_br, form, fn)) return title, fmt_name, type_name, urls, size
def get_streams_info(self, profile='shd'): for PLAYER_PLATFORM in PLAYER_PLATFORMS.copy(): params = { 'otype': 'json', 'platform': PLAYER_PLATFORM, 'vid': self.vid, 'defnpayver': 1, 'appver': PLAYER_VERSION, 'defn': profile, } content = get_content('http://vv.video.qq.com/getinfo?' + urlencode(params)) data = json.loads(match1(content, r'QZOutputJson=(.+);$')) self.logger.debug('data: ' + str(data)) if 'msg' in data: assert data['msg'] != 'vid status wrong', 'wrong vid' PLAYER_PLATFORMS.remove(PLAYER_PLATFORM) continue if PLAYER_PLATFORMS and \ profile == 'shd' and \ '"name":"shd"' not in content and \ '"name":"fhd"' not in content: for infos in self.get_streams_info('hd'): yield infos return break assert 'msg' not in data, data['msg'] #self.fp2p = data.get('fp2p') video = data['vl']['vi'][0] fn = video['fn'] title = video['ti'] td = float(video['td']) fvkey = video.get('fvkey') # Not to be absolutely accuracy. self.vip = video['drm'] self.slow = not self.vip and (video['iflag'] or video['pl']) # Priority for range fetch. cdn_url_1 = cdn_url_2 = cdn_url_3 = None for cdn in video['ul']['ui']: cdn_url = cdn['url'] # 'video.dispatch.tc.qq.com' supported keep-alive link. if cdn_url == 'http://video.dispatch.tc.qq.com/': cdn_url_3 = cdn_url # IP host. elif match1(cdn_url, '(^https?://[0-9\.]+/)'): if not cdn_url_2: cdn_url_2 = cdn_url elif not cdn_url_1: cdn_url_1 = cdn_url if self.slow: cdn_url = cdn_url_3 or cdn_url_1 or cdn_url_2 else: cdn_url = cdn_url_1 or cdn_url_2 or cdn_url_3 dt = cdn['dt'] if dt == 1: type_name = 'flv' elif dt == 2: type_name = 'mp4' else: type_name = 'unknown' _num_clips = video['cl']['fc'] for fmt in data['fl']['fi']: fmt_id = fmt['id'] fmt_name = fmt['name'] fmt_cname = fmt['cname'] size = fmt['fs'] rate = size // td fns = fn.split('.') fmt_id_num = fmt_id fmt_id_prefix = None num_clips = 0 if fmt_id_num > 100000: fmt_id_prefix = 'm' elif fmt_id_num > 10000: fmt_id_prefix = 'p' num_clips = _num_clips or 1 if fmt_id_prefix: fmt_id_name = fmt_id_prefix + str(fmt_id_num % 10000) if fns[1][0] in ('p', 'm') and not fns[1].startswith('mp'): fns[1] = fmt_id_name else: fns.insert(1, fmt_id_name) elif fns[1][0] in ('p', 'm') and not fns[1].startswith('mp'): del fns[1] urls =[] if num_clips == 0: filename = '.'.join(fns) url, vip = qq_get_final_url(cdn_url, self.vid, fmt_id, filename, fvkey, PLAYER_PLATFORM) if vip: self.vip = vip elif url: urls.append(url) else: fns.insert(-1, '1') for idx in range(1, num_clips+1): fns[-2] = str(idx) filename = '.'.join(fns) url, vip = qq_get_final_url(cdn_url, self.vid, fmt_id, filename, fvkey, PLAYER_PLATFORM) if vip: self.vip = vip break elif url: urls.append(url) yield title, fmt_name, fmt_cname, type_name, urls, size, rate