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

Code before:
        'only_matching': True,
    }]

    def _get_sign_func(self, room_id, video_id):
        return self._download_json(
            f'https://www.douyu.com/swf_api/homeH5Enc?rids={room_id}', video_id,
            note='Getting signing script')['data'][f'room{room_id}']

    def _extract_stream_formats(self, stream_formats):
        formats = []
        for stream_info in traverse_obj(stream_formats, (..., 'data')):
            stream_url = urljoin(
                traverse_obj(stream_info, 'rtmp_url'), traverse_obj(stream_info, 'rtmp_live'))
            if stream_url:
                rate_id = traverse_obj(stream_info, ('rate', {int_or_none}))
                rate_info = traverse_obj(stream_info, ('multirates', lambda _, v: v['rate'] == rate_id), get_all=False)
                formats.append({
                    'url': stream_url,
                    'format_id': str_or_none(rate_id),
                    'ext': 'mp4' if '.m3u8' in stream_url else determine_ext(stream_url),
                    'quality': rate_id % -10000 if rate_id is not None else None,
                    **traverse_obj(rate_info, {
                        'format': ('name', {str_or_none}),
                        'tbr': ('bit', {int_or_none}),
                    }),
                })
        return formats

    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)
        room_id = self._search_regex(r'\$ROOM\.room_id\s*=\s*(\d+)', webpage, 'room id')

        if self._search_regex(r'"videoLoop"\s*:\s*(\d+)', webpage, 'loop', default='') == '1':
            raise UserNotLive('The channel is auto-playing VODs', video_id=video_id)
        if self._search_regex(r'\$ROOM\.show_status\s*=\s*(\d+)', webpage, 'status', default='') == '2':
            raise UserNotLive(video_id=video_id)

        # Grab metadata from API
        params = {
            'aid': 'wp',
            'client_sys': 'wp',
            'time': int(time.time()),
        }
        params['auth'] = hashlib.md5(
            f'room/{room_id}?{urllib.parse.urlencode(params)}zNzMV1y4EMxOHS6I5WKm'.encode()).hexdigest()
        room = traverse_obj(self._download_json(
            f'http://www.douyutv.com/api/v1/room/{room_id}', video_id,
            note='Downloading room info', query=params, fatal=False), 'data')


Review comment (refactor):
Looking over this again, I realize we should do this:
```suggestion
                ext = determine_ext(stream_url)
                formats.append({
                    'url': stream_url,
                    'format_id': str_or_none(rate_id),
                    'ext': 'mp4' if ext == 'm3u8' else ext,
                    'protocol': 'm3u8_native' if ext == 'm3u8' else 'https',
                    'quality': rate_id % -10000 if rate_id is not None else None,
                    **traverse_obj(rate_info, {
                        'format': ('name', {str_or_none}),
                        'tbr': ('bit', {int_or_none}),
                    }),
                })
```
&nbsp;
but, if the URL is m3u8, are we sure that it is only a variant m3u8 and not a master m3u8? If master, we'd need to do this:

```suggestion
                ext = determine_ext(stream_url)
                if ext == 'm3u8':
                    formats.extend(self._extract_m3u8_formats(
                        stream_url, None, 'mp4', fatal=False, m3u8_id='hls'))
                else:
                    formats.append({
                        'url': stream_url,
                        'format_id': str_or_none(rate_id),
                        'ext': ext,
                        'quality': rate_id % -10000 if rate_id is not None else None,
                        **traverse_obj(rate_info, {
                            'format': ('name', {str_or_none}),
                            'tbr': ('bit', {int_or_none}),
                        }),
                    })
```
and if it must be done this way, maybe you want to add a `video_id` arg to `_extract_stream_formats` so that we have one to pass to `_extract_m3u8_formats`


Code after:
        'only_matching': True,
    }]

    def _get_sign_func(self, room_id, video_id):
        return self._download_json(
            f'https://www.douyu.com/swf_api/homeH5Enc?rids={room_id}', video_id,
            note='Getting signing script')['data'][f'room{room_id}']

    def _extract_stream_formats(self, stream_formats):
        formats = []
        for stream_info in traverse_obj(stream_formats, (..., 'data')):
            stream_url = urljoin(
                traverse_obj(stream_info, 'rtmp_url'), traverse_obj(stream_info, 'rtmp_live'))
            if stream_url:
                rate_id = traverse_obj(stream_info, ('rate', {int_or_none}))
                rate_info = traverse_obj(stream_info, ('multirates', lambda _, v: v['rate'] == rate_id), get_all=False)
                ext = determine_ext(stream_url)
                formats.append({
                    'url': stream_url,
                    'format_id': str_or_none(rate_id),
                    'ext': 'mp4' if ext == 'm3u8' else ext,
                    'protocol': 'm3u8_native' if ext == 'm3u8' else 'https',
                    'quality': rate_id % -10000 if rate_id is not None else None,
                    **traverse_obj(rate_info, {
                        'format': ('name', {str_or_none}),
                        'tbr': ('bit', {int_or_none}),
                    }),
                })
        return formats

    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(url, video_id)
        room_id = self._search_regex(r'\$ROOM\.room_id\s*=\s*(\d+)', webpage, 'room id')

        if self._search_regex(r'"videoLoop"\s*:\s*(\d+)', webpage, 'loop', default='') == '1':
            raise UserNotLive('The channel is auto-playing VODs', video_id=video_id)
        if self._search_regex(r'\$ROOM\.show_status\s*=\s*(\d+)', webpage, 'status', default='') == '2':
            raise UserNotLive(video_id=video_id)

        # Grab metadata from API
        params = {
            'aid': 'wp',
            'client_sys': 'wp',
            'time': int(time.time()),
        }
        params['auth'] = hashlib.md5(
            f'room/{room_id}?{urllib.parse.urlencode(params)}zNzMV1y4EMxOHS6I5WKm'.encode()).hexdigest()
        room = traverse_obj(self._download_json(
            f'http://www.douyutv.com/api/v1/room/{room_id}', video_id,