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

Code before:
            'id': video_id,
            'title': title,
            'formats': self._extract_png_formats(vidplayer_id),
            'is_live': True,
        }


class RTVETelevisionIE(InfoExtractor):
    IE_NAME = 'rtve.es:television'
    _VALID_URL = r'https?://(?:www\.)?rtve\.es/television/[^/]+/[^/]+/(?P<id>\d+).shtml'

    _TEST = {
        'url': 'http://www.rtve.es/television/20160628/revolucion-del-movil/1364141.shtml',
        'info_dict': {
            'id': '3069778',
            'ext': 'mp4',
            'title': 'Documentos TV - La revolución del móvil',
            'duration': 3496.948,
        },
        'params': {
            'skip_download': True,
        },
    }

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

        alacarta_url = self._search_regex(
            r'data-location="alacarta_videos"[^<]+url&quot;:&quot;(http://www\.rtve\.es/alacarta.+?)&',
            webpage, 'alacarta url', default=None)
        if alacarta_url is None:
            raise ExtractorError(
                'The webpage doesn\'t contain any video', expected=True)

        return self.url_result(alacarta_url, ie=RTVEALaCartaIE.ie_key())


Review comment (suggestion):
```suggestion
            'series': try_get(info, lambda x: x['programInfo']['title']),
```
or 
```py
            'series': traverse_obj(info, ('programInfo', 'title')),
```

Code after:
            audio_id, 'Downloading url information', query={'q': 'v2'})
        q = qualities(['Media', 'Alta', 'HQ', 'HD_READY', 'HD_FULL'])
        formats = []
        for quality, audio_url in self._decrypt_url(png):
            ext = determine_ext(audio_url)
            if ext == 'm3u8':
                formats.extend(self._extract_m3u8_formats(
                    audio_url, audio_id, 'mp4', 'm3u8_native',
                    m3u8_id='hls', fatal=False))
            elif ext == 'mpd':
                formats.extend(self._extract_mpd_formats(
                    audio_url, audio_id, 'dash', fatal=False))
            else:
                formats.append({
                    'format_id': quality,
                    'quality': q(quality),
                    'url': audio_url,
                })
        self._sort_formats(formats)
        return formats

    def _real_extract(self, url):
        audio_id = self._match_id(url)
        info = self._download_json(
            'https://www.rtve.es/api/audios/%s.json' % audio_id,
            audio_id)['page']['items'][0]

        return {
            'id': audio_id,
            'title': info['title'].strip(),
            'thumbnail': info.get('thumbnail'),
            'duration': float_or_none(info.get('duration'), 1000),
            'series': try_get(info, lambda x: x['programInfo']['title']),
            'formats': self._extract_png_formats(audio_id),
        }


class RTVEInfantilIE(RTVEALaCartaIE):
    IE_NAME = 'rtve.es:infantil'
    IE_DESC = 'RTVE infantil'
    _VALID_URL = r'https?://(?:www\.)?rtve\.es/infantil/serie/[^/]+/video/[^/]+/(?P<id>[0-9]+)/'

    _TESTS = [{
        'url': 'http://www.rtve.es/infantil/serie/cleo/video/maneras-vivir/3040283/',
        'md5': '5747454717aedf9f9fdf212d1bcfc48d',
        'info_dict': {
            'id': '3040283',
            'ext': 'mp4',
            'title': 'Maneras de vivir',
            'thumbnail': r're:https?://.+/1426182947956\.JPG',
            'duration': 357.958,