def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) t_a = match1(html, '"keywords" content="([^"]+)') info.title = t_a.split(',')[0] info.artist = t_a.split(',')[1] replay_url = match1(html, '"m3u8":"([^"]+)') if replay_url: replay_url = replay_url.replace('\/','/') info.live = False info.stream_types.append('current') info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [replay_url], 'size': float('inf')} return info self.vid = match1(html, '"sn":"([^"]+)') channel = match1(html, '"channel":"([^"]+)') api_url = 'http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}&_ostype=flash&_delay=0&_sign=null&_ver=13'.format(channel, self.vid, SID, time.time(),random.random()) encoded_json = get_content(api_url) decoded_json = base64.decodestring(compact_bytes(encoded_json[0:3]+ encoded_json[6:], 'utf-8')).decode('utf-8') video_data = json.loads(decoded_json) live_url = video_data['main'] info.live = True info.stream_types.append('current') info.streams['current'] = {'container': 'flv', 'video_profile': 'current', 'src' : [live_url], 'size': float('inf')} return info
def prepare(self): info = VideoInfo(self.name) html = get_content(self.url) video_type = match1(html, 'VideoType":"([^"]+)"') if video_type == 'LIVE': info.live = True elif not video_type == 'VOD': raise NotImplementedError('Unknown_video_type') info.title = match1(html, '<title>([^<]+)').split("_")[0] if info.live: rtmp_id = match1(html, 'videoId":"([^"]+)"').replace('\\/', '/') real_url = self.live_base + '/' + rtmp_id + '.m3u8' info.stream_types, info.streams = load_m3u8_playlist(real_url) else: vod_m3u8 = self.vod_base + '/' + match1( html, 'VideoID":"([^"]+)').replace('\\/', '/') info.stream_types.append('current') info.streams['current'] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [vod_m3u8], 'size': 0 } return info
def prepare(self): info = VideoInfo(self.name) info.live = True self.vid = self.url[self.url.rfind('/')+1:].split(".")[0] json_request_url = 'http://www.yizhibo.com/live/h5api/get_basic_live_info?scid={}'.format(self.vid) content = json.loads(get_content(json_request_url)) assert content['result'] == 1, "Error : {}".format(content['result']) info.title = content['data']['live_title'] info.artist = content['data']['nickname'] info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [content['data']['play_url']], 'size': float('inf')} info.stream_types.append('current') return info
def prepare(self): info = VideoInfo(self.name) info.live = True self.vid = self.url[self.url.rfind('/') + 1:].split(".")[0] json_request_url = 'http://www.yizhibo.com/live/h5api/get_basic_live_info?scid={}'.format( self.vid) content = json.loads(get_content(json_request_url)) assert content['result'] == 1, "Error : {}".format(content['result']) info.title = content['data']['live_title'] info.artist = content['data']['nickname'] info.streams['current'] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [content['data']['play_url']], 'size': float('inf') } info.stream_types.append('current') return info
def prepare(self): info = VideoInfo(self.name) html = get_content(self.url) video_type = match1(html, 'VideoType":"([^"]+)"') if video_type == 'LIVE': info.live = True elif not video_type == 'VOD': raise NotImplementedError('Unknown_video_type') info.title = match1(html, '<title>([^<]+)').split("_")[0] if info.live: rtmp_id = match1(html, 'videoId":"([^"]+)"').replace('\\/','/') real_url = self.live_base+'/'+rtmp_id+'.m3u8' info.stream_types, info.streams = load_m3u8_playlist(real_url) else: vod_m3u8 = self.vod_base + '/' + match1(html, 'VideoID":"([^"]+)').replace('\\/','/') info.stream_types.append('current') info.streams['current'] = {'container': 'm3u8', 'video_profile': 'current', 'src' : [vod_m3u8], 'size': 0} return info
def prepare(self): info = VideoInfo(self.name, True) html = get_content(self.url) t_a = match1(html, '"keywords" content="([^"]+)') info.title = t_a.split(',')[0] info.artist = t_a.split(',')[1] replay_url = match1(html, '"m3u8":"([^"]+)') if replay_url: replay_url = replay_url.replace('\/', '/') info.live = False info.stream_types.append('current') info.streams['current'] = { 'container': 'm3u8', 'video_profile': 'current', 'src': [replay_url], 'size': float('inf') } return info self.vid = match1(html, '"sn":"([^"]+)') channel = match1(html, '"channel":"([^"]+)') api_url = 'http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}&_ostype=flash&_delay=0&_sign=null&_ver=13'.format( channel, self.vid, SID, time.time(), random.random()) encoded_json = get_content(api_url) decoded_json = base64.decodestring( compact_bytes(encoded_json[0:3] + encoded_json[6:], 'utf-8')).decode('utf-8') video_data = json.loads(decoded_json) live_url = video_data['main'] info.stream_types.append('current') info.streams['current'] = { 'container': 'flv', 'video_profile': 'current', 'src': [live_url], 'size': float('inf') } return info
def prepare(self): assert javascript_is_supported, "No JS Interpreter found, can't parse douyu live!" info = VideoInfo(self.name, True) add_header("Referer", 'https://www.douyu.com') html = get_content(self.url) self.vid = match1(html, '\$ROOM\.room_id\s*=\s*(\d+)', 'room_id\s*=\s*(\d+)', '"room_id.?":(\d+)', 'data-onlineid=(\d+)') title = match1(html, 'Title-headlineH2">([^<]+)<') artist = match1(html, 'Title-anchorName" title="([^"]+)"') if not title or not artist: html = get_content('https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) room_data = json.loads(html) if room_data['error'] == 0: room_data = room_data['data'] title = room_data['room_name'] artist = room_data['owner_name'] rstr = r"[\/\\\:\*\?\"\<\>\|\-\`\'\ ]" info.title = re.sub(rstr, "_", title) info.artist = re.sub(rstr, "_", artist) info.live = False html_h5enc = get_content( 'https://www.douyu.com/swf_api/homeH5Enc?rids=' + self.vid) data = json.loads(html_h5enc) assert data['error'] == 0, data['msg'] js_enc = data['data']['room' + self.vid] try: # try load local .js file first # from https://cdnjs.com/libraries/crypto-js from pkgutil import get_data js_md5 = get_data(__name__, 'crypto-js-md5.min.js') if not isinstance(js_md5, str): js_md5 = js_md5.decode() except IOError: js_md5 = get_content( 'https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js' ) names_dict = { 'debugMessages': get_random_name(8), 'decryptedCodes': get_random_name(8), 'resoult': get_random_name(8), '_ub98484234': get_random_name(8), 'workflow': match1(js_enc, 'function ub98484234\(.+?\Weval\((\w+)\);'), } js_dom = ''' {debugMessages} = {{{decryptedCodes}: []}}; window = {{}}; document = {{}}; '''.format(**names_dict) js_patch = ''' {debugMessages}.{decryptedCodes}.push({workflow}); var replacer = function (match, p1, p2, offset, string) {{ return p1 ? ";" + p2 : ";!" + p2; }}; {workflow} = {workflow}.replace(/;(!?)(\w+ && \(function\()/g, replacer); var subWorkflow = /eval\((\w+)\);/.exec({workflow}); if (subWorkflow) {{ var subPatch = ` {debugMessages}.{decryptedCodes}.push('sub workflow: ' + subWorkflow); subWorkflow = subWorkflow.replace(/;(!?)(\\\\w+ && \\\\(function\\\\()/g, replacer); eval(subWorkflow); `.replace(/subWorkflow/g, subWorkflow[1]); {workflow} = {workflow}.replace(subWorkflow[0], subPatch); }} eval({workflow}); '''.format(**names_dict) js_debug = ''' var {_ub98484234} = ub98484234; ub98484234 = function(p1, p2, p3){{ try {{ var resoult = {_ub98484234}(p1, p2, p3); {debugMessages}.{resoult} = resoult; }}catch(e) {{ {debugMessages}.{resoult} = e.message; }} return {debugMessages}; }}; '''.format(**names_dict) js_enc = js_enc.replace('eval({workflow});'.format(**names_dict), js_patch) js_ctx = JSEngine() js_ctx.eval(js_md5) js_ctx.eval(js_dom) js_ctx.eval(js_enc) js_ctx.eval(js_debug) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', self.vid, did, tt) self.logger.debug('ub98484234: %s', ub98484234) ub98484234 = ub98484234[names_dict['resoult']] params = { 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})'), 'cdn': 'ws-h5', 'iar': 0, 'ive': 0 } 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) error_msg = get_live_info() assert len(info.stream_types), error_msg info.stream_types = sorted(info.stream_types, key=self.stream_ids.index) return info