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

Code before:
            'repost_count': int,
            'thumbnail': 'https://static.vvvvid.it/img/thumbs/Dynit/Jojo/Jojo_S05Ep01-t.jpg',
            'season': 'Season 5',
            'season_number': 5,
        },
        'params': {
            'skip_download': True,
            'format': 'mp4',
        },
    }, {
        'url': 'https://www.vvvvid.it/show/434/perche-dovrei-guardarlo-di-dario-moccia/437/489048',
        'only_matching': True
    }]
    _conn_id = None
    _default_user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.50 Safari/537.37'
    _blocked_user_agents_regex = r'^Mozilla/5\.0 \(Windows NT 10\.0; Win64; x64\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/[\d.]+ Safari/537\.36$'
    _headers = {}

    def _get_headers(self):
        geo_verification_headers = self.geo_verification_headers()
        http_headers = self.get_param('http_headers', {})
        headers = {**http_headers, **geo_verification_headers}
        user_agent = headers.get('User-Agent', None)
        if not user_agent or re.match(self._blocked_user_agents_regex, user_agent):
            headers['User-Agent'] = self._default_user_agent
        return headers

    def _real_initialize(self, *args, **kwargs):
        self._headers = self._get_headers()
        self._conn_id = self._download_json(
            'https://www.vvvvid.it/user/login',
            None, headers=self._headers)['data']['conn_id']

    def _download_info(self, show_id, path, video_id, fatal=True, query=None):
        q = {
            'conn_id': self._conn_id,
        }
        if query:
            q.update(query)
        response = self._download_json(
            'https://www.vvvvid.it/vvvvid/ondemand/%s/%s' % (show_id, path),
            video_id, headers=self._headers, query=q, fatal=fatal)
        if not (response or fatal):
            return
        if response.get('result') == 'error':
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, response['message']), expected=True)
        return response['data']

    def _extract_common_video_info(self, video_data):
        return {

Review comment (performance):
Just add the custom user agent unconditionally imo. It's unlikely anyone wants custom UA here unless IE breaks.

Also, `_headers` looks like it should be a `@cached_property`

Code after:
            'like_count': int,
            'repost_count': int,
            'thumbnail': 'https://static.vvvvid.it/img/thumbs/Dynit/Jojo/Jojo_S05Ep01-t.jpg',
            'season': 'Season 5',
            'season_number': 5,
        },
        'params': {
            'skip_download': True,
            'format': 'mp4',
        },
    }, {
        'url': 'https://www.vvvvid.it/show/434/perche-dovrei-guardarlo-di-dario-moccia/437/489048',
        'only_matching': True
    }]
    _conn_id = None

    @functools.cached_property
    def _headers(self):
        return {
            **self.geo_verification_headers(),
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.50 Safari/537.37',
        }

    def _real_initialize(self):
        self._conn_id = self._download_json(
            'https://www.vvvvid.it/user/login',
            None, headers=self._headers)['data']['conn_id']

    def _download_info(self, show_id, path, video_id, fatal=True, query=None):
        q = {
            'conn_id': self._conn_id,
        }
        if query:
            q.update(query)
        response = self._download_json(
            'https://www.vvvvid.it/vvvvid/ondemand/%s/%s' % (show_id, path),
            video_id, headers=self._headers, query=q, fatal=fatal)
        if not (response or fatal):
            return
        if response.get('result') == 'error':
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, response['message']), expected=True)
        return response['data']

    def _extract_common_video_info(self, video_data):
        return {
            'thumbnail': video_data.get('thumbnail'),
            'episode_id': str_or_none(video_data.get('id')),
        }

    def _real_extract(self, url):