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

Code before:
            'id': '31406',
            'ext': 'mp3',
            'title': 'Das Leben schwer nehmen, ist einfach zu anstrengend',
            'channel': 'SR 1',
            'description': 'md5:3e03fd556af831ad984d0add7175fb0c',
            'duration': 1769.0,
            'release_date': '20230717',
            'series': 'Abendrot',
            'series_id': 'SR1_AB_P',
            'thumbnail': r're:https?://.+\.jpg',
        },
    }]

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

        if description == 'Der gewünschte Beitrag ist leider nicht mehr vorhanden.':
            raise ExtractorError(f'Video {video_id} is no longer available', expected=True)

        player_url = traverse_obj(webpage, (
            {find_element(tag='div', id=f'player{video_id}', html=True)},
            {extract_attributes}, 'data-mediacollection-ardplayer',
            {lambda x: self._proto_relative_url(x)},
        ))
        article = traverse_obj(webpage, (
            {find_element(cls='article__content')},
            {find_element(tag='p')}, {clean_html},
        ))
        cls_common = 'teaser__image__caption__text teaser__image__caption__text--'

        return {
            **self._extract_media_info(player_url, webpage, video_id),
            'id': video_id,
            'title': traverse_obj(webpage, (
                {find_element(cls='ardplayer-title')}, {str.strip})),
            'channel': traverse_obj(webpage, (
                {find_element(cls=f'{cls_common}subheadline')},
                {lambda x: x.split('|')[0]}, {str.strip})),
            'description': description,
            'duration': parse_duration(self._search_regex(
                r'(\d{2}:\d{2}:\d{2})', article, 'duration')),
            'release_date': unified_strdate(self._search_regex(
                r'(\d{2}\.\d{2}\.\d{4})', article, 'release_date')),
            'series': traverse_obj(webpage, (
                {find_element(cls=f'{cls_common}headline')}, {str.strip})),
            'series_id': traverse_obj(webpage, (
                {find_element(cls='teaser__link', html=True)},
                {extract_attributes}, 'href', {parse_qs}, 'sen', ..., {str}, any)),
            'thumbnail': self._og_search_thumbnail(webpage),

Review comment (refactor):
- the `lambda` in the `_proto_relative_url` transformation is redundant
- might as well `require` here since `_extract_media_info` is fatal later

```suggestion
        player_url = traverse_obj(webpage, (
            {find_element(tag='div', id=f'player{video_id}', html=True)},
            {extract_attributes}, 'data-mediacollection-ardplayer',
            {self._proto_relative_url}, {require('player URL')}))
```

Code after:
            'thumbnail': r're:https?://.+\.jpg',
        },
    }, {
        'url': 'https://www.sr-mediathek.de/index.php?seite=7&id=31406&pnr=&tbl=pf',
        'info_dict': {
            'id': '31406',
            'ext': 'mp3',
            'title': 'Das Leben schwer nehmen, ist einfach zu anstrengend',
            'channel': 'SR 1',
            'description': 'md5:3e03fd556af831ad984d0add7175fb0c',
            'duration': 1769.0,
            'release_date': '20230717',
            'series': 'Abendrot',
            'series_id': 'SR1_AB_P',
            'thumbnail': r're:https?://.+\.jpg',
        },
    }]

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

        if description == 'Der gewünschte Beitrag ist leider nicht mehr vorhanden.':
            raise ExtractorError(f'Video {video_id} is no longer available', expected=True)

        player_url = traverse_obj(webpage, (
            {find_element(tag='div', id=f'player{video_id}', html=True)},
            {extract_attributes}, 'data-mediacollection-ardplayer',
            {self._proto_relative_url}, {require('player URL')}))
        article = traverse_obj(webpage, (
            {find_element(cls='article__content')},
            {find_element(tag='p')}, {clean_html}))

        return {
            **self._extract_media_info(player_url, webpage, video_id),
            'id': video_id,
            'title': traverse_obj(webpage, (
                {find_element(cls='ardplayer-title')}, {clean_html})),
            'channel': traverse_obj(webpage, (
                {find_element(cls=f'{self._CLS_COMMON}subheadline')},
                {lambda x: x.split('|')[0]}, {clean_html})),
            'description': description,
            'duration': parse_duration(self._search_regex(
                r'(\d{2}:\d{2}:\d{2})', article, 'duration')),
            'release_date': unified_strdate(self._search_regex(
                r'(\d{2}\.\d{2}\.\d{4})', article, 'release_date')),
            'series': traverse_obj(webpage, (
                {find_element(cls=f'{self._CLS_COMMON}headline')}, {clean_html})),
            'series_id': traverse_obj(webpage, (
                {find_element(cls='teaser__link', html=True)},