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

Code before:
        elif not club_joined:
            self.raise_login_required('This video is for members only', metadata_available=True)

        formats = []

        def get_video_info(*items, get_first=True, **kwargs):
            return traverse_obj(api_data, ('video', *items), get_all=not get_first, **kwargs)

        dmc_data = traverse_obj(api_data, (
            'media', 'delivery', 'movie', {
                'audios': 'audios',
                'videos': 'videos',
                'protocols': ('session', 'protocols'),
            }, {lambda data: data if all(key in data for key in ['audios', 'videos', 'protocols']) else None},
        ))
        if dmc_data:
            for (audio_quality, video_quality, protocol) in itertools.product(
                    dmc_data['audios'], dmc_data['videos'], dmc_data['protocols']):
                fmt = self._extract_format_for_quality(video_id, audio_quality, video_quality, protocol)
                if fmt:
                    formats.append(fmt)

        dms_data = traverse_obj(api_data, ({
            'videos': ('media', 'domand', 'videos', ..., {
                lambda item: item['id'] if item['isAvailable'] else None
            }),
            'audios': ('media', 'domand', 'audios', ..., {
                lambda item: (item['id'], {
                    'format_id': str(parse_bitrate(item['id'])),
                    'abr': float_or_none(item['bitRate'], scale=1000),
                    'asr': item['samplingRate'],
                    'acodec': 'aac',
                    'ext': 'm4a',
                }) if item['isAvailable'] else None
            }),
            'accessRightKey': ('media', 'domand', 'accessRightKey'),
            'track_id': ('client', 'watchTrackId'),
        }, {
            'videos': 'videos',
            'audios': ('audios', {lambda items: dict(items)}),
            'accessRightKey': 'accessRightKey',
            'track_id': 'track_id',
        }, {
            lambda data: data if all(key in data for key in [
                'videos', 'audios', 'accessRightKey', 'track_id',
            ]) else None
        }))
        if dms_data:
            dms_m3u8_url = traverse_obj(self._download_json(
                f'https://nvapi.nicovideo.jp/v1/watch/{video_id}/access-rights/hls', video_id,
                data=json.dumps({

Review comment (suggestion):
would be more appropriate to filter rather than transform here, e.g.
```suggestion
            'videos': ('media', 'domand', 'videos', lambda _, v: v['isAvailable'], 'id', {str}),
```

Code after:
                **traverse_obj(audios, (lambda _, v: audio_fmt['format_id'].startswith(v['id']), {
                    'format_id': ('id', {str}),
                    'abr': ('bitRate', {functools.partial(float_or_none, scale=1000)}),
                    'asr': ('samplingRate', {int_or_none}),
                }), get_all=False),
                'acodec': 'aac',
                'ext': 'm4a',
            }

        # Sort before removing dupes to keep the format dicts with the lowest tbr
        video_fmts = sorted((fmt for fmt in dms_fmts if fmt['vcodec'] != 'none'), key=lambda f: f['tbr'])
        self._remove_duplicate_formats(video_fmts)
        # Calculate the true vbr/tbr by subtracting the lowest abr
        min_abr = min(traverse_obj(audios, (..., 'bitRate', {float_or_none})), default=0) / 1000
        for video_fmt in video_fmts:
            video_fmt['tbr'] -= min_abr
            video_fmt['format_id'] = f'video-{video_fmt["tbr"]:.0f}'
            yield video_fmt

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

        try:
            webpage, handle = self._download_webpage_handle(
                'https://www.nicovideo.jp/watch/' + video_id, video_id)
            if video_id.startswith('so'):
                video_id = self._match_id(handle.url)

            api_data = self._parse_json(self._html_search_regex(
                'data-api-data="([^"]+)"', webpage,
                'API data', default='{}'), video_id)
        except ExtractorError as e:
            try:
                api_data = self._download_json(
                    'https://www.nicovideo.jp/api/watch/v3/%s?_frontendId=6&_frontendVersion=0&actionTrackId=AAAAAAAAAA_%d' % (video_id, round(time.time() * 1000)), video_id,
                    note='Downloading API JSON', errnote='Unable to fetch data')['data']
            except ExtractorError:
                if not isinstance(e.cause, HTTPError):
                    raise
                webpage = e.cause.response.read().decode('utf-8', 'replace')
                error_msg = self._html_search_regex(
                    r'(?s)<section\s+class="(?:(?:ErrorMessage|WatchExceptionPage-message)\s*)+">(.+?)</section>',
                    webpage, 'error reason', default=None)
                if not error_msg:
                    raise
                raise ExtractorError(clean_html(error_msg), expected=True)

        club_joined = traverse_obj(api_data, ('channel', 'viewer', 'follow', 'isFollowed', {bool}))
        if club_joined is None:
            fail_msg = self._html_search_regex(
                r'<p[^>]+\bclass="fail-message"[^>]*>(?P<msg>.+?)</p>',