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

Code before:
        duration = int_or_none(self._search_regex(
            r'data-duration=["\'](\d+)', webpage, 'duration', default=None))

        return {
            'id': audio_id,
            'url': 'http://media.rozhlas.cz/_audio/%s.mp3' % audio_id,
            'title': title,
            'description': description,
            'duration': duration,
            'vcodec': 'none',
        }


class RozhlasVltavaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:(?:vltava|wave|radiozurnal|dvojka|plus|sport|d-dur|jazz|junior|pohoda)\.rozhlas|english\.radio)\.cz/[a-z|-]*-(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://wave.rozhlas.cz/papej-masicko-porcujeme-a-bilancujeme-filmy-a-serialy-ktere-letos-zabily-8891337',
        'md5': 'ba2fdbc1242fc16771c7695d271ec355',
        'info_dict': {
            'id': '8891337',
            'ext': 'mp3',
            'title': 'md5:1c6d29fb9564e1f17fc1bb83ae7da0bc',
            'description': 'md5:bbab1431c3472304b4863faea414cd2b',
            'duration': 1574
        }
    }]

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

        player_div = re.findall("<div class=\"mujRozhlasPlayer\" data-player='.*'>", webpage)[0]  # Use utils.get_element_text_and_html_by_tag() instead when it accepts less strict html.

        data = self._parse_json(extract_attributes(player_div).get('data-player'), video_id).get('data')

        entries = []
        for entry in data.get('playlist'):
            formats = []
            for audio_link in entry.get('audioLinks'):
                formats.append({
                    'url': audio_link.get('url'),
                    'ext': audio_link.get('variant'),
                    'format_id': audio_link.get('variant'),
                    'abr': audio_link.get('bitrate'),
                    'acodec': audio_link.get('variant'),
                    'vcodec': 'none',
                })
            entries.append({
                'id': self._match_id(url),  # Prefering to user entry.get('meta').get('ga').get('contentId') for id. Using this because of tests.
                'title': entry.get('title'),
                'description': entry.get('meta').get('ga').get('contentEvent'),

Review comment (bug):
Definition is wrong. This happens to pass the test due to a quirk (bug?) in the test runner. Add `playlist` key to the definition. E.g. https://github.com/yt-dlp/yt-dlp/blob/ce03e9b90acef7a8b59b1193e32cbd9898c93ad0/yt_dlp/extractor/afreecatv.py#L51-L79

Code after:
            'url': 'http://media.rozhlas.cz/_audio/%s.mp3' % audio_id,
            'title': title,
            'description': description,
            'duration': duration,
            'vcodec': 'none',
        }


class RozhlasVltavaIE(InfoExtractor):
    _VALID_URL = r'https?://(?:\w+\.rozhlas|english\.radio)\.cz/[\w-]+-(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://wave.rozhlas.cz/papej-masicko-porcujeme-a-bilancujeme-filmy-a-serialy-ktere-letos-zabily-8891337',
        'md5': 'ba2fdbc1242fc16771c7695d271ec355',
        'info_dict': {
            'id': 8891337,
            'title': 'md5:21f99739d04ab49d8c189ec711eef4ec',
        },
        'playlist_count': 1,
        'playlist': [{
            'md5': 'ba2fdbc1242fc16771c7695d271ec355',
            'info_dict': {
                'id': '10520988',
                'ext': 'mp3',
                'title': 'Papej masíčko! Porcujeme a bilancujeme filmy a seriály, které to letos zabily',
                'description': 'md5:1c6d29fb9564e1f17fc1bb83ae7da0bc',
                'duration': 1574,
                'artist': 'Aleš Stuchlý',
                'channel_id': 'radio-wave',
            },
        }]
    }, {
        'url': 'https://wave.rozhlas.cz/poslechnete-si-neklid-podcastovy-thriller-o-vine-strachu-a-vztahu-ktery-zasel-8554744',
        'info_dict': {
            'id': 8554744,
            'title': 'Poslechněte si Neklid. Podcastový thriller o vině, strachu a vztahu, který zašel příliš daleko',
        },
        'playlist_count': 5,
        'playlist': [{
            'md5': '93d4109cf8f40523699ae9c1d4600bdd',
            'info_dict': {
                'id': '9890713',
                'ext': 'mp3',
                'title': 'Neklid #1',
                'description': '1. díl: Neklid: 1. díl',
                'duration': 1025,
                'artist': 'Josef Kokta',
                'channel_id': 'radio-wave',
                'chapter': 'Neklid #1',
                'chapter_number': 1,
            },
        }, {