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

Code before:
        if playlist_type:
            playlist_info = self._graphql_query(urn, self._QUERY_PLAYLIST)['show']
            episodes = playlist_info['items']['nodes']
            entries = []
            for episode in episodes:
                entries.append(self.url_result(
                    episode['url'],
                    ie=ARDAudiothekIE.ie_key()))
            return self.playlist_result(entries, urn, display_id=urn, **traverse_obj(playlist_info, {
                'title': ('title', {str}),
                'description': ('description', {str}),
            }))

        item = self._graphql_query(urn, self._QUERY_ITEM)['item']
        return {
            'formats': traverse_obj(item, (
                'audioList', lambda _, v: url_or_none(v['href']), {
                    'url': 'href',
                    'format_id': ('distributionType', {str}),
                })),
            'id': urn,
            **traverse_obj(item, {
                'channel': ('programSet', 'publicationService', 'organizationName', {str}),
                'description': ('description', {str}),
                'duration': ('duration', {int_or_none}),
                'series': ('show', 'title'),
                'episode_number': ('episodeNumber', {int_or_none}),
                'thumbnail': ('image', 'url1X1', {lambda v: v.split('?')[0] if isinstance(v, str) else None}),
                'timestamp': ('startDate', {parse_iso8601}),
                'title': ('title', {str}),
            }),
        }


Review comment (suggestion):
```suggestion
                'series': ('show', 'title', {str}),
```

Code after:
                'thumbnail': ('image', 'url1X1', {url_or_none}, {update_url(query=None)}),
                'timestamp': ('startDate', {parse_iso8601}),
                'title': ('title', {str}),
            }),
        }


class ARDAudiothekPlaylistIE(ARDAudiothekBaseIE):
    _VALID_URL = r'https:?//(?:www\.)?ardaudiothek\.de/sendung/(?P<playlist>[\w-]+)/(?P<id>urn:ard:show:[a-f0-9]{16})'

    _TESTS = [{
        'url': 'https://www.ardaudiothek.de/sendung/mia-insomnia/urn:ard:show:c405aa26d9a4060a/',
        'info_dict': {
            'display_id': 'mia-insomnia',
            'title': 'Mia Insomnia',
            'id': 'urn:ard:show:c405aa26d9a4060a',
            'description': 'md5:d9ceb7a6b4d26a4db3316573bb564292',
        },
        'playlist_mincount': 37,
    }, {
        'url': 'https://www.ardaudiothek.de/sendung/100-berlin/urn:ard:show:4d248e0806ce37bc/',
        'only_matching': True,
    }]

    _QUERY_PLAYLIST = '''
    query($id: ID!) {
        show(id: $id) {
            title
            description
            items(filter: { isPublished: { equalTo: true } }) {
                nodes {
                    url
                }
            }
        }
    }'''

    def _real_extract(self, url):
        urn, playlist = self._match_valid_url(url).group('id', 'playlist')
        playlist_info = self._graphql_query(urn, self._QUERY_PLAYLIST)['show']
        entries = []
        for url in traverse_obj(playlist_info, ('items', 'nodes', ..., 'url', {url_or_none})):
            entries.append(self.url_result(url, ie=ARDAudiothekIE))
        return self.playlist_result(entries, urn, display_id=playlist, **traverse_obj(playlist_info, {
            'title': ('title', {str}),
            'description': ('description', {str}),
        }))