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

Code before:
    traverse_obj,
    unified_timestamp,
    unsmuggle_url,
    url_or_none,
    urlencode_postdata,
    variadic,
)


class BilibiliBaseIE(InfoExtractor):
    _FORMAT_ID_RE = re.compile(r'-(\d+)\.m4s\?')
    _WBI_KEY_CACHE_TIMEOUT = 30  # exact expire timeout is unclear, use 30s for one session
    _wbi_key_cache = {}

    def _has_no_login_cookie(self):
        return self._get_cookies('https://api.bilibili.com').get('SESSDATA') is None

    def check_missing_formats(self, play_info, formats):
        parsed_qualites = set(traverse_obj(formats, (..., 'quality')))
        missing_formats = [
            traverse_obj(missing, 'new_description', 'display_desc', 'quality')
            for missing in traverse_obj(play_info, (
                'support_formats', lambda _, v: v['quality'] not in parsed_qualites))]
        if missing_formats:
            self.to_screen(f'Format(s) {", ".join(map(str, missing_formats))} are missing; '
                           f'you have to login or become premium member to download them. {self._login_hint()}')

    def extract_formats(self, play_info):
        format_names = {
            r['quality']: traverse_obj(r, 'new_description', 'display_desc')
            for r in traverse_obj(play_info, ('support_formats', lambda _, v: v['quality']))
        }

        audios = traverse_obj(play_info, ('dash', (None, 'dolby'), 'audio', ..., {dict}))
        flac_audio = traverse_obj(play_info, ('dash', 'flac', 'audio'))
        if flac_audio:
            audios.append(flac_audio)
        formats = [{
            'url': traverse_obj(audio, 'baseUrl', 'base_url', 'url'),
            'ext': mimetype2ext(traverse_obj(audio, 'mimeType', 'mime_type')),
            'acodec': traverse_obj(audio, ('codecs', {str.lower})),
            'vcodec': 'none',
            'tbr': float_or_none(audio.get('bandwidth'), scale=1000),
            'filesize': int_or_none(audio.get('size')),
            'format_id': str_or_none(audio.get('id')),
        } for audio in audios]

        formats.extend({
            'url': traverse_obj(video, 'baseUrl', 'base_url', 'url'),
            'ext': mimetype2ext(traverse_obj(video, 'mimeType', 'mime_type')),
            'fps': float_or_none(traverse_obj(video, 'frameRate', 'frame_rate')),

Review comment (suggestion):
```suggestion
            self.to_screen(
                f'Format(s) {missing_formats} are missing; you have to login or '
                f'become a premium member to download them. {self._login_hint()}')
```

Code after:
    traverse_obj,
    unified_timestamp,
    unsmuggle_url,
    url_or_none,
    urlencode_postdata,
    variadic,
)


class BilibiliBaseIE(InfoExtractor):
    _FORMAT_ID_RE = re.compile(r'-(\d+)\.m4s\?')
    _WBI_KEY_CACHE_TIMEOUT = 30  # exact expire timeout is unclear, use 30s for one session
    _wbi_key_cache = {}

    @property
    def is_logged_in(self):
        return bool(self._get_cookies('https://api.bilibili.com').get('SESSDATA'))

    def _check_missing_formats(self, play_info, formats):
        parsed_qualities = set(traverse_obj(formats, (..., 'quality')))
        missing_formats = join_nonempty(*[
            traverse_obj(fmt, 'new_description', 'display_desc', 'quality')
            for fmt in traverse_obj(play_info, (
                'support_formats', lambda _, v: v['quality'] not in parsed_qualities))], delim=', ')
        if missing_formats:
            self.to_screen(
                f'Format(s) {missing_formats} are missing; you have to login or '
                f'become a premium member to download them. {self._login_hint()}')

    def extract_formats(self, play_info):
        format_names = {
            r['quality']: traverse_obj(r, 'new_description', 'display_desc')
            for r in traverse_obj(play_info, ('support_formats', lambda _, v: v['quality']))
        }

        audios = traverse_obj(play_info, ('dash', (None, 'dolby'), 'audio', ..., {dict}))
        flac_audio = traverse_obj(play_info, ('dash', 'flac', 'audio'))
        if flac_audio:
            audios.append(flac_audio)
        formats = [{
            'url': traverse_obj(audio, 'baseUrl', 'base_url', 'url'),
            'ext': mimetype2ext(traverse_obj(audio, 'mimeType', 'mime_type')),
            'acodec': traverse_obj(audio, ('codecs', {str.lower})),
            'vcodec': 'none',
            'tbr': float_or_none(audio.get('bandwidth'), scale=1000),
            'filesize': int_or_none(audio.get('size')),
            'format_id': str_or_none(audio.get('id')),
        } for audio in audios]

        formats.extend({
            'url': traverse_obj(video, 'baseUrl', 'base_url', 'url'),