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

Code before:
            'tags': ['Atomenergie', 'Endlager', 'hoch-radioaktiver Abfall', 'Endlagersuche', 'Atommüll', 'Atomendlager', 'Gorleben', 'Deutschland'],
            'thumbnail': 'https://www.bpb.de/cache/images/3/315813_teaser_16x9_1240.png?92A94',
            'title': 'Folge 1: Eine Einführung',
            'uploader': 'Bundeszentrale für politische Bildung',
        },
    }, {
        'url': 'https://www.bpb.de/517806/die-weltanschauung-der-neuen-rechten/',
        'info_dict': {
            '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),

Review comment (suggestion):
```suggestion
    _TITLE_RE = re.compile('(?P<title>[^<]*)<[^>]+>(?P<series>[^<]*)')
```

Code after:
            'tags': ['Atomenergie', 'Endlager', 'hoch-radioaktiver Abfall', 'Endlagersuche', 'Atommüll', 'Atomendlager', 'Gorleben', 'Deutschland'],
            'thumbnail': 'https://www.bpb.de/cache/images/3/315813_teaser_16x9_1240.png?92A94',
            'title': 'Folge 1: Eine Einführung',
            'uploader': 'Bundeszentrale für politische Bildung',
        },
    }, {
        'url': 'https://www.bpb.de/517806/die-weltanschauung-der-neuen-rechten/',
        'info_dict': {
            '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,