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

Code before:
                'uploader_id': ('creator', 'id', {str}),
                'channel': ('channel', 'title', {str}),
                'channel_id': ('channel', 'id', {str}),
                'release_timestamp': ('releaseDate', {parse_iso8601}),
            }),
        }

        items = []
        for media in traverse_obj(post_data, (('videoAttachments', 'audioAttachments'), ...)):
            media_id = media['id']
            media_typ = media.get('type') or 'video'

            metadata = self._download_json(
                f'{self._BASE_URL}/api/v3/content/{media_typ}', media_id, query={'id': media_id},
                note=f'Downloading {media_typ} metadata', impersonate=self._IMPERSONATE_TARGET)

            stream = self._download_json(
                f'{self._BASE_URL}/api/v3/delivery/info', media_id,
                query={'scenario': 'onDemand', 'entityId': media_id},
                note=f'Downloading {media_typ} stream data',
                impersonate=self._IMPERSONATE_TARGET)

            cdn_base_url = traverse_obj(stream, ('groups', 0, 'origins', 0, 'url', {str}))

            formats = []
            for variant in traverse_obj(stream, ('groups', 0, 'variants', ...)):
                url = urljoin(cdn_base_url, variant.get('url'))
                format_id = variant.get('name')
                hls_aes = {}
                m3u8_data = None

                # If we need impersonation for the API, then we need it for HLS keys too: extract in advance
                if self._IMPERSONATE_TARGET is not None:
                    m3u8_data = self._download_webpage(
                        url, media_id, fatal=False, impersonate=self._IMPERSONATE_TARGET, headers=self._HEADERS,
                        note=join_nonempty('Downloading', format_id, 'm3u8 information', delim=' '),
                        errnote=join_nonempty('Failed to download', format_id, 'm3u8 information', delim=' '))
                    if not m3u8_data:
                        continue

                    key_url = self._search_regex(
                        r'#EXT-X-KEY:METHOD=AES-128,URI="(https?://[^"]+)"',
                        m3u8_data, 'HLS AES key URI', default=None)
                    if key_url:
                        urlh = self._request_webpage(
                            key_url, media_id, fatal=False, impersonate=self._IMPERSONATE_TARGET, headers=self._HEADERS,
                            note=join_nonempty('Downloading', format_id, 'HLS AES key', delim=' '),
                            errnote=join_nonempty('Failed to download', format_id, 'HLS AES key', delim=' '))
                        if urlh:
                            hls_aes['key'] = urlh.read().hex()


Review comment (bug):
Additional fix needed for floatplane, as we otherwise might crash later on the partition call due to an empty url field
```suggestion
            for variant in traverse_obj(stream, ('groups', 0, 'variants', lambda _, v: v['url'])):
```

Code after:
                'uploader_id': ('creator', 'id', {str}),
                'channel': ('channel', 'title', {str}),
                'channel_id': ('channel', 'id', {str}),
                'release_timestamp': ('releaseDate', {parse_iso8601}),
            }),
        }

        items = []
        for media in traverse_obj(post_data, (('videoAttachments', 'audioAttachments'), ...)):
            media_id = media['id']
            media_typ = media.get('type') or 'video'

            stream = self._download_json(
                f'{self._BASE_URL}/api/v3/delivery/info', media_id,
                query={'scenario': 'onDemand', 'entityId': media_id},
                note=f'Downloading {media_typ} stream data',
                impersonate=self._IMPERSONATE_TARGET)

            metadata = self._download_json(
                f'{self._BASE_URL}/api/v3/content/{media_typ}', media_id,
                f'Downloading {media_typ} metadata', query={'id': media_id},
                fatal=False, impersonate=self._IMPERSONATE_TARGET)

            cdn_base_url = traverse_obj(stream, (
                'groups', 0, 'origins', ..., 'url', {url_or_none}, any, {require('cdn base url')}))

            formats = []
            for variant in traverse_obj(stream, ('groups', 0, 'variants', lambda _, v: v['url'])):
                format_url = urljoin(cdn_base_url, variant['url'])
                format_id = traverse_obj(variant, ('name', {str}))
                hls_aes = {}
                m3u8_data = None

                # If we need impersonation for the API, then we need it for HLS keys too: extract in advance
                if self._IMPERSONATE_TARGET is not None:
                    m3u8_data = self._download_webpage(
                        format_url, media_id, fatal=False, impersonate=self._IMPERSONATE_TARGET, headers=self._HEADERS,
                        note=join_nonempty('Downloading', format_id, 'm3u8 information', delim=' '),
                        errnote=join_nonempty('Failed to download', format_id, 'm3u8 information', delim=' '))
                    if not m3u8_data:
                        continue

                    key_url = self._search_regex(
                        r'#EXT-X-KEY:METHOD=AES-128,URI="(https?://[^"]+)"',
                        m3u8_data, 'HLS AES key URI', default=None)
                    if key_url:
                        urlh = self._request_webpage(
                            key_url, media_id, fatal=False, impersonate=self._IMPERSONATE_TARGET, headers=self._HEADERS,
                            note=join_nonempty('Downloading', format_id, 'HLS AES key', delim=' '),
                            errnote=join_nonempty('Failed to download', format_id, 'HLS AES key', delim=' '))
                        if urlh: