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

Code before:
            'thumbnail': 'https://www.ndr.de/fernsehen/screenshot983938_v-contentxl.jpg',
            'description': 'md5:700f6de264010585012a72f97b0ac0c9',
            'series': 'extra 3',
            'channel': 'NDR Fernsehen',
            'upload_date': '20201111',
            'duration': 1749,
        }
    }, {
        'url': 'http://www.ndr.de/info/La-Valette-entgeht-der-Hinrichtung,audio51535.html',
        'info_dict': {
            'id': 'audio51535',
            'ext': 'mp3',
            'title': 'La Valette entgeht der Hinrichtung',
            'thumbnail': 'https://www.ndr.de/mediathek/mediathekbild140_v-podcast.jpg',
            'description': 'md5:22f9541913a40fe50091d5cdd7c9f536',
            'upload_date': '20140729',
            'duration': 884.0,
        },
        'expected_warnings': ['unable to extract json url'],
    }]

    def _real_extract(self, url):
        mobj = self._match_valid_url(url)
        display_id = next(group for group in mobj.groups() if group)
        id = mobj.group('id')
        webpage = self._download_webpage(url, display_id)
        formats = []

        base_url = 'https://www.ndr.de'
        json_url = self._search_regex(r'<iframe[^>]+src=\"([^\"]+)_theme-ndrde[^\.]*\.html\"', webpage,
                                      'json url', fatal=False)
        if json_url:
            data_json = self._download_json(base_url + json_url.replace('ardplayer_image', 'ardjson_image') + '.json',
                                            id, fatal=False)
            info_json = data_json.get('_info', {})
            media_json = try_get(data_json, lambda x: x['_mediaArray'][0]['_mediaStreamArray'])
            for media in media_json:
                if media.get('_quality') == 'auto':
                    formats.extend(self._extract_m3u8_formats(media['_stream'], id))
            subtitles = {}
            sub_url = data_json.get('_subtitleUrl')
            if sub_url:
                subtitles.setdefault('de', []).append({
                    'url': base_url + sub_url,
                })
            self._sort_formats(formats)
            return {
                'id': id,
                'title': info_json.get('clipTitle'),
                'thumbnail': base_url + data_json.get('_previewImage'),
                'description': info_json.get('clipDescription'),

Review comment (refactor):
this code is duplicate from the BaseIE
you can use `_extract_embed` instead like what the extractor was already doing

Code after:
            'id': 'audio51535',
            'ext': 'mp3',
            'title': 'La Valette entgeht der Hinrichtung',
            'thumbnail': 'https://www.ndr.de/mediathek/mediathekbild140_v-podcast.jpg',
            'description': 'md5:22f9541913a40fe50091d5cdd7c9f536',
            'upload_date': '20140729',
            'duration': 884.0,
        },
        'expected_warnings': ['unable to extract json url'],
    }]

    def _extract_embed(self, webpage, display_id, id):
        formats = []
        base_url = 'https://www.ndr.de'
        json_url = self._search_regex(r'<iframe[^>]+src=\"([^\"]+)_theme-ndrde[^\.]*\.html\"', webpage,
                                      'json url', fatal=False)
        if json_url:
            data_json = self._download_json(base_url + json_url.replace('ardplayer_image', 'ardjson_image') + '.json',
                                            id, fatal=False)
            info_json = data_json.get('_info', {})
            media_json = try_get(data_json, lambda x: x['_mediaArray'][0]['_mediaStreamArray'])
            for media in media_json:
                if media.get('_quality') == 'auto':
                    formats.extend(self._extract_m3u8_formats(media['_stream'], id))
            subtitles = {}
            sub_url = data_json.get('_subtitleUrl')
            if sub_url:
                subtitles.setdefault('de', []).append({
                    'url': base_url + sub_url,
                })
            self._sort_formats(formats)
            return {
                'id': id,
                'title': info_json.get('clipTitle'),
                'thumbnail': base_url + data_json.get('_previewImage'),
                'description': info_json.get('clipDescription'),
                'series': info_json.get('seriesTitle') or None,
                'channel': info_json.get('channelTitle'),
                'upload_date': unified_strdate(info_json.get('clipDate')),
                'duration': data_json.get('_duration'),
                'formats': formats,
                'subtitles': subtitles,
            }
        else:
            json_url = base_url + self._search_regex(r'apiUrl\s?=\s?\'([^\']+)\'', webpage, 'json url').replace(
                '_belongsToPodcast-', '')
            data_json = self._download_json(json_url, id, fatal=False)
            return {
                'id': id,
                'title': data_json.get('title'),
                'thumbnail': base_url + data_json.get('poster'),