def cmd5x(s): # the param src below uses salt h2l6suw16pbtikmotf0j79cej4n8uw13 # 01010031010000000000 # 01010031010010000000 # 01080031010000000000 # 01080031010010000000 # 03020031010000000000 # 03020031010010000000 # 03030031010000000000 # 03030031010010000000 # 02020031010000000000 # 02020031010010000000 #if len(s) < 6: # return '0' #return md5(s + 'h2l6suw16pbtikmotf0j79cej4n8uw13') # out of date global js_ctx if js_ctx is None: from ykdl.util.jsengine import JSEngine assert JSEngine, "No JS Interpreter found, can't use cmd5x!" # code from https://zsaim.github.io/2019/08/23/Iqiyi-cmd5x-Analysis/ try: # try load local .js file first from pkgutil import get_data js = get_data(__name__, 'cmd5x.js') except IOError: js = get_content( 'https://raw.githubusercontent.com/ZSAIm/ZSAIm.github.io/master/misc/2019-08-23/iqiyi_cmd5x.js' ) js_ctx = JSEngine(js) return js_ctx.call('cmd5x_exports.cmd5x', s)
def prepare_data(self): html = get_content(self.url) js = match1(html, 'window\.__NUXT__=(.+);</script>') js_ctx = JSEngine() data = js_ctx.eval(js) self.logger.debug('video_data: \n%s', data) try: self.url = data['data'][0]['playUrl'] except KeyError: self.data = data else: self.prepare_data()
def init_jsengine(): global js_ctx if js_ctx is None: from ykdl.util.jsengine import JSEngine assert JSEngine, "No JS Interpreter found, can't use cmd5x!" js_ctx = JSEngine(init_global=True) from pkgutil import get_data # code from https://zsaim.github.io/2019/08/23/Iqiyi-cmd5x-Analysis/ try: # try load local .js file first js = get_data(__name__, 'cmd5x.js') except IOError: # origin https://raw.githubusercontent.com/ZSAIm/ZSAIm.github.io/master/misc/2019-08-23/iqiyi_cmd5x.js js = get_content( 'https://raw.githubusercontent.com/zhangn1985/ykdl/master/ykdl/extractors/iqiyi/cmd5x.js' ) js_ctx.append(js) # code from https://github.com/lldy/js try: # try load local .js file first js = get_data(__name__, 'cmd5x_iqiyi3.js') except IOError: js = get_content( 'https://raw.githubusercontent.com/zhangn1985/ykdl/master/ykdl/extractors/iqiyi/cmd5x_iqiyi3.js' ) js_ctx.append(js)
def prepare(self): info = VideoInfo(self.name, True) if not self.vid: self.vid = match1(self.url, '/(\d+)') if not self.url: self.url = 'https://egame.qq.com/' + self.vid html = get_content(self.url) js_nuxt = match1(html, '<script>window.__NUXT__=(.+?)</script>') js_ctx = JSEngine() data = js_ctx.eval(js_nuxt) self.logger.debug('data => %s', data) state = data.get('state', {}) error = data.get('error') or state.get('errors') assert not error, 'error: {}!!'.format(error) liveInfo = state['live-info']['liveInfo'] videoInfo = liveInfo['videoInfo'] profileInfo = liveInfo['profileInfo'] assert profileInfo['isLive'], 'error: live show is not on line!!' title = videoInfo['title'] info.artist = artist = profileInfo['nickName'] info.title = u'{} - {}'.format(title, artist) for s in videoInfo['streamInfos']: stream = self.lv_2_id[s['levelType']] info.stream_types.append(stream) info.streams[stream] = { 'container': 'flv', 'video_profile': s['desc'], 'src': [s['playUrl']], 'size': float('inf') } info.stream_types = sorted(info.stream_types, key=self.stream_ids.index) 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') title = None artist = None html_room_info = None self.vid = match1(self.url, 'douyu.com/(\d+)') if self.vid: try: html_room_info = get_content( 'https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) except: self.vid = None if not self.vid: html = get_content(self.url) self.vid = match1(html, 'room_id\s*=\s*(\d+)', '"room_id.?":(\d+)', 'data-onlineid=(\d+)') title = match1(html, 'Title-headlineH2">([^<]+)<') artist = match1(html, 'Title-anchorName" title="([^"]+)"') if not artist: html_room_info = html_room_info or get_content( 'https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) data = json.loads(html_room_info) if data['error'] == 0: title = data['data']['room_name'] artist = data['data']['owner_name'] info.title = u'{} - {}'.format(title, artist) info.artist = artist 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 isinstance(js_md5, bytes): 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' ) js_ctx = JSEngine(js_md5) js_ctx.eval(js_enc) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', self.vid, did, tt) self.logger.debug('ub98484234: ' + ub98484234) params = { 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})'), 'cdn': '', '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']] 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) 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
def ub98484234(js_enc, extractor, params): 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}: []}}; if (!this.window) {{window = {{}};}} if (!this.document) {{document = {{}};}} '''.format(**names_dict) js_patch = ''' {debugMessages}.{decryptedCodes}.push({workflow}); var patchCode = function(workflow) {{ var testVari = /(\w+)=(\w+)\([\w\+]+\);.*?(\w+)="\w+";/.exec(workflow); if (testVari && testVari[1] == testVari[2]) {{ {workflow} += testVari[1] + "[" + testVari[3] + "] = function() {{return true;}};"; }} }}; patchCode({workflow}); var subWorkflow = /(?:\w+=)?eval\((\w+)\)/.exec({workflow}); if (subWorkflow) {{ var subPatch = ( `{debugMessages}.{decryptedCodes}.push('sub workflow: ' + subWorkflow); patchCode(subWorkflow);` ).replace(/subWorkflow/g, subWorkflow[1]) + subWorkflow[0]; {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.append(js_md5) js_ctx.append(js_dom) js_ctx.append(js_enc) js_ctx.append(js_debug) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', extractor.vid, did, tt) extractor.logger.debug('ub98484234: %s', ub98484234) ub98484234 = ub98484234[names_dict['resoult']] params.update({ 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})') })
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'] info.title = u'{} - {}'.format(title, artist) info.artist = artist 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}: []}}; if (!this.window) {{window = {{}};}} if (!this.document) {{document = {{}};}} '''.format(**names_dict) js_patch = ''' {debugMessages}.{decryptedCodes}.push({workflow}); var patchCode = function(workflow) {{ var testVari = /(\w+)=(\w+)\([\w\+]+\);.*?(\w+)="\w+";/.exec(workflow); if (testVari && testVari[1] == testVari[2]) {{ {workflow} += testVari[1] + "[" + testVari[3] + "] = function() {{return true;}};"; }} }}; patchCode({workflow}); var subWorkflow = /(?:\w+=)?eval\((\w+)\)/.exec({workflow}); if (subWorkflow) {{ var subPatch = ( "{debugMessages}.{decryptedCodes}.push('sub workflow: ' + subWorkflow);" + "patchCode(subWorkflow);" ).replace(/subWorkflow/g, subWorkflow[1]) + subWorkflow[0]; {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': '', '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']] 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) 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
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') title = None artist = None html_room_info = None self.vid = match1(self.url, 'douyu.com/(\d+)') if self.vid: try: html_room_info = get_content('https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) except: self.vid = None if not self.vid: html = get_content(self.url) self.vid = match1(html, 'room_id\s*=\s*(\d+)', '"room_id.?":(\d+)', 'data-onlineid=(\d+)') title = match1(html, 'Title-headlineH2">([^<]+)<') artist = match1(html, 'Title-anchorName" title="([^"]+)"') if not artist: html_room_info = html_room_info or get_content('https://open.douyucdn.cn/api/RoomApi/room/' + self.vid) data = json.loads(html_room_info) if data['error'] == 0: title = data['data']['room_name'] artist = data['data']['owner_name'] info.title = u'{} - {}'.format(title, artist) info.artist = artist 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 isinstance(js_md5, bytes): 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') js_ctx = JSEngine(js_md5) js_ctx.eval(js_enc) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', self.vid, did, tt) self.logger.debug('ub98484234: ' + ub98484234) params = { 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})'), 'cdn': '', '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']] 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) 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
def ub98484234(js_enc, extractor, params): 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}: []}}; if (!this.window) {{window = {{}};}} if (!this.document) {{document = {{}};}} '''.format(**names_dict) js_patch = ''' {debugMessages}.{decryptedCodes}.push({workflow}); var patchCode = function(workflow) {{ var testVari = /(\w+)=(\w+)\([\w\+]+\);.*?(\w+)="\w+";/.exec(workflow); if (testVari && testVari[1] == testVari[2]) {{ {workflow} += testVari[1] + "[" + testVari[3] + "] = function() {{return true;}};"; }} }}; patchCode({workflow}); var subWorkflow = /(?:\w+=)?eval\((\w+)\)/.exec({workflow}); if (subWorkflow) {{ var subPatch = ( "{debugMessages}.{decryptedCodes}.push('sub workflow: ' + subWorkflow);" + "patchCode(subWorkflow);" ).replace(/subWorkflow/g, subWorkflow[1]) + subWorkflow[0]; {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.append(js_md5) js_ctx.append(js_dom) js_ctx.append(js_enc) js_ctx.append(js_debug) did = uuid.uuid4().hex tt = str(int(time.time())) ub98484234 = js_ctx.call('ub98484234', extractor.vid, did, tt) extractor.logger.debug('ub98484234: %s', ub98484234) ub98484234 = ub98484234[names_dict['resoult']] params.update({ 'v': match1(ub98484234, 'v=(\d+)'), 'did': did, 'tt': tt, 'sign': match1(ub98484234, 'sign=(\w{32})') })
def prepare(self): info = VideoInfo(self.name, True) js_ctx = JSEngine('if (!this.window) {window = {};}') js_ctx.append(js_m) vid = match1(self.url, '/live/.*?(\d+)') if vid is None: html = get_content(self.url) js_data = match1(html, 'window.__NUXT__=(.+?)</script>') data = js_ctx.eval(js_data) self.logger.debug('data:\n%s', data) data = data['data'][0] data = data.get('videoInfo', data) else: data = get_content( 'https://www.heibaizhibo.com/api/index/live?id=' + vid) self.logger.debug('data:\n%s', data) data = json.loads(data) msg = data['message'] assert '成功' in msg, msg data = data['data']['detail'] try: qllist = data['hd'] except KeyError: # anchor qllist = data['hdlist'] title = data['anchorInfo']['title'] artist = data['anchorInfo']['nickname'] else: title = '[{}] {}({})'.format(data['eventName'], data['homeName'], data['awayName']) assert data['playCode'], 'live video is offline!' data = data['playCode'][0] artist = data['gtvDesc'] or data['name'] info.title = '{} - {}'.format(title, artist) info.artist = artist params = { 'gtvId': data.get('gtvId'), 'id': data.get('id', 0), 'type': 3, 'source': 2, 'liveType': 3, # 1: rtmp, 2: m3u8, 3: flv } if not params['gtvId']: del params['gtvId'] for ql in qllist: params['defi'] = ql['defi'] data_live = json.loads( get_content( 'https://sig.heibaizhibo.com/signal-front/live/matchLiveInfo?' + urlencode(params))) self.logger.debug('data_live:\n%s', data_live) msg = data_live['msg'] assert '成功' in msg, msg data_live = data_live['data'][0] assert data_live['score'] >= 0, 'live video is offline!' url = js_ctx.call('vp', data_live['liveUrl']) stream = ql['defi'].upper() info.stream_types.append(stream) info.streams[stream] = { 'container': 'flv', 'video_profile': ql['name'], 'src': [url], 'size': float('inf') } break # seems the same quality? info.stream_types = sorted(info.stream_types, key=self.stream_ids.index) return info
def prepare(self): add_default_handler(HTTPCookieProcessor) install_default_handlers() add_header('Referer', self.url) info = VideoInfo(self.name) if self.url and not self.vid: self.vid = match1(self.url, 'com/[bl]/\d+/(\d+).html') if self.vid is None: self.vid = match1(self.url, 'com/s/(\d+).html') if self.vid is None: html = get_content(self.url) if match1(self.url, 'com/h/(\d+).html'): from ykdl.util.jsengine import JSEngine assert JSEngine, 'No JS Interpreter found!!!' js_ctx = JSEngine() js = match1(html, '<script>window.__NUXT__=(.+);</script>') data = str(js_ctx.eval(js)) self.vid = match1(data, "PartId': '(\d+)'") else: self.vid = match1( html, 'window.location = "/b/\d+/(\d+).html"', r'routePath:"\\u002Fl\\u002F\d+\\u002F(\d+).html"', 'vid[=:]\D?(\d+)') assert self.vid, 'can not find video!!!' did = str(uuid.uuid4()) tk2 = generate_tk2(did) api_info_url = 'https://pcweb.api.mgtv.com/player/video?tk2={}&video_id={}&type=pch5'.format( tk2, self.vid) meta = json.loads(get_content(api_info_url)) self.logger.debug('meta >\n%s', meta) assert meta['code'] == 200, '[failed] code: {}, msg: {}'.format( meta['code'], meta['msg']) assert meta['data'], '[Failed] Video info not found.' pm2 = meta['data']['atc']['pm2'] info.title = meta['data']['info']['title'] + ' ' + meta['data'][ 'info']['desc'] api_source_url = 'https://pcweb.api.mgtv.com/player/getSource?pm2={}&tk2={}&video_id={}&type=pch5'.format( pm2, tk2, self.vid) meta = json.loads(get_content(api_source_url)) assert meta['code'] == 200, '[failed] code: {}, msg: {}'.format( meta['code'], meta['msg']) assert meta['data'], '[Failed] Video source not found.' data = meta['data'] domain = data['stream_domain'][0] for lstream in data['stream']: lurl = lstream['url'] if lurl: lurl = '{}{}&did={}'.format(domain, lurl, did) url = json.loads(get_content(lurl))['info'] video_profile = lstream['name'] stream = self.profile_2_types[video_profile] info.streams[stream] = { 'container': 'm3u8', 'video_profile': video_profile, 'src': [url] } info.stream_types.append(stream) info.stream_types = sorted(info.stream_types, key=self.supported_stream_types.index) info.extra['referer'] = self.url return info
def prepare_data(self): html = get_content(self.url) js = match1(html, 'window\.__NUXT__=(.+);</script>') js_ctx = JSEngine() self.data = js_ctx.eval(js) self.logger.debug('video_data: \n%s', self.data)