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

Code before:
            'id': '517806',
            'ext': 'mp3',
            'creator': 'Bundeszentrale für politische Bildung',
            'description': 'md5:594689600e919912aade0b2871cc3fed',
            'release_date': '20230127',
            'series': 'Vorträge des Fachtags "Modernisierer. Grenzgänger. Anstifter. Sechs Jahrzehnte \'Neue Rechte\'"',
            'tags': ['Rechtsextremismus', 'Konservatismus', 'Konservativismus', 'neue Rechte', 'Rechtspopulismus', 'Schnellroda', 'Deutschland'],
            'thumbnail': 'https://www.bpb.de/cache/images/6/517806_teaser_16x9_1240.png?7A7A0',
            'title': 'Die Weltanschauung der "Neuen Rechten"',
            'uploader': 'Bundeszentrale für politische Bildung',
        },
    }, {
        'url': 'https://www.bpb.de/mediathek/reihen/zahlen-und-fakten-soziale-situation-filme/520153/zahlen-und-fakten-die-soziale-situation-in-deutschland-migration/',
        'only_matching': True,
    }]

    BASE_URL = 'https://www.bpb.de'
    _TITLE_RE = re.compile('(?P<title>.*?)<[^>]+>(?P<series>[^<]*)')

    def _parse_vue_attributes(self, name, string, video_id):
        attributes = extract_attributes(self._search_regex(rf'(<{name}(?:"[^"]*?"|[^>])*>)', string, name))

        for key, value in attributes.items():
            if key.startswith(':'):
                attributes[key] = self._parse_json(value, video_id, transform_source=js_to_json, fatal=False)

        return attributes

    @staticmethod
    def _process_source(source):
        url = url_or_none(source['src'])
        if not url:
            return None

        source_type = source.get('type', '')
        extension = mimetype2ext(source_type)
        note = url.rpartition('.')[0].rpartition('_')[2] if source_type.startswith('video') else None
        return {
            'url': url,
            'ext': extension,
            'quality': 10 if note == 'high' else 0,
            'format_note': note,
            'format_id': join_nonempty(extension, note),
        }

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

        title_result = traverse_obj(webpage, ({html_get_element(cls='opening-header__title')}, {self._TITLE_RE.match}))
        json_lds = list(self._yield_json_ld(webpage, video_id, fatal=False))

Review comment (refactor):
Just a note that it might be useful to eventually generalize this and add it as an `InfoExtractor` helper method, since it is very similar to `ZaikoBaseIE._parse_vue_element_attrs` (but not similar enough as-is)

Code after:
            'id': '517806',
            'ext': 'mp3',
            'creator': 'Bundeszentrale für politische Bildung',
            'description': 'md5:594689600e919912aade0b2871cc3fed',
            'release_date': '20230127',
            'series': 'Vorträge des Fachtags "Modernisierer. Grenzgänger. Anstifter. Sechs Jahrzehnte \'Neue Rechte\'"',
            'tags': ['Rechtsextremismus', 'Konservatismus', 'Konservativismus', 'neue Rechte', 'Rechtspopulismus', 'Schnellroda', 'Deutschland'],
            'thumbnail': 'https://www.bpb.de/cache/images/6/517806_teaser_16x9_1240.png?7A7A0',
            'title': 'Die Weltanschauung der "Neuen Rechten"',
            'uploader': 'Bundeszentrale für politische Bildung',
        },
    }, {
        'url': 'https://www.bpb.de/mediathek/reihen/zahlen-und-fakten-soziale-situation-filme/520153/zahlen-und-fakten-die-soziale-situation-in-deutschland-migration/',
        'only_matching': True,
    }]

    _TITLE_RE = re.compile('(?P<title>[^<]*)<[^>]+>(?P<series>[^<]*)')

    def _parse_vue_attributes(self, name, string, video_id):
        attributes = extract_attributes(self._search_regex(rf'(<{name}(?:"[^"]*?"|[^>])*>)', string, name))

        for key, value in attributes.items():
            if key.startswith(':'):
                attributes[key] = self._parse_json(value, video_id, transform_source=js_to_json, fatal=False)

        return attributes

    @staticmethod
    def _process_source(source):
        url = url_or_none(source['src'])
        if not url:
            return None

        source_type = source.get('type', '')
        extension = mimetype2ext(source_type)
        is_video = source_type.startswith('video')
        note = url.rpartition('.')[0].rpartition('_')[2] if is_video else None

        return {
            'url': url,
            'ext': extension,
            'vcodec': None if is_video else 'none',
            'quality': 10 if note == 'high' else 0,
            'format_note': note,
            'format_id': join_nonempty(extension, note),
        }

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