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

Code before:
        'super': '1920x1080',
        'high': '1280x720',
        'normal': '852x480',
    }

    def _real_extract(self, url):
        url = url.replace('vmobile.', 'v.')
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)

        video_info = self._search_json(
            r'<script>window\.\$DATA=', webpage,
            'video info', video_id, transform_source=js_to_json)

        js_sign_func = self._search_js_sign_func(webpage)
        form_data = {
            'vid': video_id,
            **self._calc_sign(js_sign_func, video_id, video_info['ROOM']['point_id']),
        }
        url_info = self._download_json(
            'https://v.douyu.com/api/stream/getStreamUrl', video_id,
            data=urlencode_postdata(form_data), note="Downloading video formats")

        formats = []
        for name, url in traverse_obj(url_info, ('data', 'thumb_video')).items():
            video_url = traverse_obj(url, ('url', {url_or_none}))
            if video_url:
                formats.append({
                    'format': self._FORMATS.get(name),
                    'format_id': name,
                    'url': video_url,
                    'quality': self._QUALITIES.get(name),
                    'ext': 'ts' if '.m3u8' in video_url else determine_ext(video_url),
                    **parse_resolution(self._RESOLUTIONS.get(name))
                })
            else:
                self.to_screen(
                    f'"{self._FORMATS.get(name, name)}" format may require logging in. {self._login_hint()}')

        return {
            'id': video_id,
            'formats': formats,
            **traverse_obj(video_info, ('DATA', {
                'title': ('content', 'title', {str_or_none}),
                'uploader': ('content', 'author', {str_or_none}),
                'uploader_id': ('content', 'up_id', {str_or_none}),
                'duration': ('content', 'video_duration', {int_or_none}),
                'thumbnail': ('content', 'video_pic', {url_or_none}),
                'timestamp': ('content', 'create_time', {int_or_none}),
                'view_count': ('content', 'view_num', {int_or_none}),

Review comment (suggestion):
```suggestion
        for name, url in traverse_obj(url_info, ('data', 'thumb_video', {dict.items}, ...)):
```

Code after:
    _RESOLUTIONS = {
        'super': '1920x1080',
        'high': '1280x720',
        'normal': '852x480',
    }

    def _real_extract(self, url):
        url = url.replace('vmobile.', 'v.')
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)

        video_info = self._search_json(
            r'<script>\s*window\.\$DATA\s*=', webpage,
            'video info', video_id, transform_source=js_to_json)

        js_sign_func = self._search_js_sign_func(webpage)
        form_data = {
            'vid': video_id,
            **self._calc_sign(js_sign_func, video_id, video_info['ROOM']['point_id']),
        }
        url_info = self._download_json(
            'https://v.douyu.com/api/stream/getStreamUrl', video_id,
            data=urlencode_postdata(form_data), note="Downloading video formats")

        formats = []
        for name, url in traverse_obj(url_info, ('data', 'thumb_video', {dict.items}, ...)):
            video_url = traverse_obj(url, ('url', {url_or_none}))
            if video_url:
                ext = determine_ext(video_url)
                formats.append({
                    'format': self._FORMATS.get(name),
                    'format_id': name,
                    'url': video_url,
                    'quality': self._QUALITIES.get(name),
                    'ext': 'mp4' if ext == 'm3u8' else ext,
                    'protocol': 'm3u8_native' if ext == 'm3u8' else 'https',
                    **parse_resolution(self._RESOLUTIONS.get(name))
                })
            else:
                self.to_screen(
                    f'"{self._FORMATS.get(name, name)}" format may require logging in. {self._login_hint()}')

        return {
            'id': video_id,
            'formats': formats,
            **traverse_obj(video_info, ('DATA', {
                'title': ('content', 'title', {str}),
                'uploader': ('content', 'author', {str}),
                'uploader_id': ('content', 'up_id', {str_or_none}),
                'duration': ('content', 'video_duration', {int_or_none}),