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

Code before:
            'thumbnail': r're:^https?://.*\.(jpg|jpeg|png)$'
        },
        'skip': 'According to the copyright owner\'s request, you may only watch the video after you are premium member.'
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        episode_id = video_id[2:]
        webpage = self._download_webpage(url, video_id)

        if '您所在的地区无法观看本片' in webpage:
            raise GeoRestrictedError('This video is restricted')
        elif '正在观看预览，大会员免费看全片' in webpage:
            self.raise_login_required('This video is for premium members only')

        headers = {'Referer': url, **self.geo_verification_headers()}
        play_info = self._download_json(
            'https://api.bilibili.com/pgc/player/web/v2/playurl', video_id,
            'Extracting episode', query={'fnval': '4048', 'ep_id': episode_id},
            headers=headers)
        if play_info['code'] == -10403:
            self.raise_login_required('This video is for premium members only')
        play_info = play_info['result']['video_info']

        formats = self.extract_formats(play_info)
        if not formats and ('成为大会员抢先看' in webpage or '开通大会员观看' in webpage):
            self.raise_login_required('This video is for premium members only')

        bangumi_info = self._download_json(
            'https://api.bilibili.com/pgc/view/web/season', video_id, 'Get episode details',
            query={'ep_id': episode_id}, headers=headers)['result']

        episode_number, episode_info = next((
            (idx, ep) for idx, ep in enumerate(traverse_obj(
                bangumi_info, ('episodes', ..., {dict})), 1)
            if str_or_none(ep.get('id')) == episode_id), (1, {}))

        season_id = bangumi_info.get('season_id')
        season_number = season_id and next((
            idx + 1 for idx, e in enumerate(
                traverse_obj(bangumi_info, ('seasons', ...)))
            if e.get('season_id') == season_id
        ), None)

        aid = episode_info.get('aid')

        return {
            'id': video_id,
            'formats': formats,
            **traverse_obj(bangumi_info, {
                'series': ('series', 'series_title', {str}),

Review comment (suggestion):
to go along with the `play_info` suggestion above:
```suggestion
        if not formats and (premium_only or '成为大会员抢先看' in webpage or '开通大会员观看' in webpage):
```

Code after:
            'thumbnail': r're:^https?://.*\.(jpg|jpeg|png)$'
        },
        'skip': 'According to the copyright owner\'s request, you may only watch the video after you are premium member.'
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        episode_id = video_id[2:]
        webpage = self._download_webpage(url, video_id)

        if '您所在的地区无法观看本片' in webpage:
            raise GeoRestrictedError('This video is restricted')
        elif '正在观看预览，大会员免费看全片' in webpage:
            self.raise_login_required('This video is for premium members only')

        headers = {'Referer': url, **self.geo_verification_headers()}
        play_info = self._download_json(
            'https://api.bilibili.com/pgc/player/web/v2/playurl', video_id,
            'Extracting episode', query={'fnval': '4048', 'ep_id': episode_id},
            headers=headers)
        premium_only = play_info.get('code') == -10403
        play_info = traverse_obj(play_info, ('result', 'video_info', {dict})) or {}

        formats = self.extract_formats(play_info)
        if not formats and (premium_only or '成为大会员抢先看' in webpage or '开通大会员观看' in webpage):
            self.raise_login_required('This video is for premium members only')

        bangumi_info = self._download_json(
            'https://api.bilibili.com/pgc/view/web/season', video_id, 'Get episode details',
            query={'ep_id': episode_id}, headers=headers)['result']

        episode_number, episode_info = next((
            (idx, ep) for idx, ep in enumerate(traverse_obj(
                bangumi_info, ('episodes', ..., {dict})), 1)
            if str_or_none(ep.get('id')) == episode_id), (1, {}))

        season_id = bangumi_info.get('season_id')
        season_number = season_id and next((
            idx + 1 for idx, e in enumerate(
                traverse_obj(bangumi_info, ('seasons', ...)))
            if e.get('season_id') == season_id
        ), None)

        aid = episode_info.get('aid')

        return {
            'id': video_id,
            'formats': formats,
            **traverse_obj(bangumi_info, {
                'series': ('series', 'series_title', {str}),
                'series_id': ('series', 'series_id', {str_or_none}),