Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/bilibili.py (Python)

Code before:
            'only_matching': True
        }
    ]

    def _call_api_base(self, path, video_id):
        json = self._download_json('https://api.live.bilibili.com' + path, video_id)
        if json.get('code') != 0:
            if json.get('message'):
                raise ExtractorError(json.get('message'))
            else:
                raise ExtractorError('Unable to download JSON metadata')
        return json.get('data')

    def _call_api_info(self, room_id):
        json = self._call_api_base(f'/room/v1/Room/get_info?id={room_id}', room_id)
        if json.get('live_status') == 0:
            raise ExtractorError('Streamer is not live')
        return json

    def _call_api_stream(self, room_id, qn):
        json = self._call_api_base(f'/xlive/web-room/v2/index/getRoomPlayInfo?room_id={room_id}&no_playurl=0&mask=0&qn={qn}&platform=web&protocol=0,1&format=0,2&codec=0,1',
                                   room_id)
        return json

    def _real_extract(self, url):
        room_id = self._match_valid_url(url).group('room_id')
        room_data = self._call_api_info(room_id)
        formats = []
        qns = [
            {
                'qn': 80,
                'desc': '流畅',
                'quality': -5,
            }, {
                'qn': 150,
                'desc': '高清',
                'quality': -4,
            }, {
                'qn': 250,
                'desc': '超清',
                'quality': -3,
            }, {
                'qn': 400,
                'desc': '蓝光',
                'quality': -2,
            }, {
                'qn': 10000,
                'desc': '原画',
                'quality': -1,
            }, {
                'qn': 20000,

Review comment (suggestion):
```suggestion
        room_id = self._match_id(url)
```
rename the group accordingly

Code after:
        'url': 'https://live.bilibili.com/196?broadcast_type=0&is_room_feed=1?spm_id_from=333.999.space_home.strengthen_live_card.click',
        'only_matching': True
    }]

    _FORMATS = {
        80: {'format_id': 'low', 'format_note': '流畅'},
        150: {'format_id': 'high_res', 'format_note': '高清'},
        250: {'format_id': 'ultra_high_res', 'format_note': '超清'},
        400: {'format_id': 'blue_ray', 'format_note': '蓝光'},
        10000: {'format_id': 'source', 'format_note': '原画'},
        20000: {'format_id': '4K', 'format_note': '4K'},
        30000: {'format_id': 'dolby', 'format_note': '杜比'},
    }

    _quality = staticmethod(qualities(list(_FORMATS)))

    def _call_api(self, path, room_id, query):
        api_result = self._download_json(f'https://api.live.bilibili.com/{path}', room_id, query=query)
        if api_result.get('code') != 0:
            raise ExtractorError(api_result.get('message') or 'Unable to download JSON metadata')
        return api_result.get('data') or {}

    def _parse_formats(self, qn, fmt):
        for codec in fmt.get('codec') or []:
            if codec.get('current_qn') != qn:
                continue
            for url_info in codec['url_info']:
                yield {
                    'url': f'{url_info["host"]}{codec["base_url"]}{url_info["extra"]}',
                    'ext': fmt.get('format_name'),
                    'vcodec': codec.get('codec_name'),
                    'quality': self._quality(qn),
                    **self._FORMATS[qn],
                }

    def _real_extract(self, url):
        room_id = self._match_id(url)
        room_data = self._call_api('room/v1/Room/get_info', room_id, {'id': room_id})
        if room_data.get('live_status') == 0:
            raise ExtractorError('Streamer is not live', expected=True)

        formats = []
        for qn in self._FORMATS.keys():
            stream_data = self._call_api('xlive/web-room/v2/index/getRoomPlayInfo', room_id, {
                'room_id': room_id,
                'qn': qn,
                'codec': '0,1',
                'format': '0,2',
                'mask': '0',
                'no_playurl': '0',
                'platform': 'web',