Example #1
0
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)
Example #2
0
 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()
Example #3
0
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)
Example #4
0
    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
Example #5
0
File: live.py Project: wwqgtxx/ykdl
    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
Example #6
0
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})')
    })
Example #7
0
    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
Example #8
0
File: live.py Project: wwqgtxx/ykdl
    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
Example #9
0
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})')
    })
Example #10
0
    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
Example #11
0
    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
Example #12
0
 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)