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

Code before:
            'title': 'Funktionale Programmierung und Verifikation (IN0003)',
            'id': '2022/S/fpv',
        },
        'params': {
            'noplaylist': False,
        },
        'playlist_count': 13,
    }, {
        'url': 'https://live.rbg.tum.de/course/2022/W/set',
        'info_dict': {
            'title': 'SET FSMPIC',
            'id': '2022/W/set',
        },
        'params': {
            'noplaylist': False,
        },
        'playlist_count': 6,
    }, {
        # new URL
        'url': 'https://tum.live/course/2023/S/linalginfo',
        'only_matching': True,
    }, ]

    def _real_extract(self, url):
        course_id = self._match_id(url)
        hostname = self._match_valid_url(url).group('hostname')
        webpage = self._download_webpage(url, course_id)

        lecture_series_title = self._html_search_regex(r'(?si)<h1.*?>(.*)</h1>', webpage, 'title')

        lecture_urls = []
        for lecture_url in re.findall(r'(?i)href="/w/(.+)(?<!/cam)(?<!/pres)(?<!/chat)"', webpage):
            lecture_urls.append(self.url_result(hostname + '/w/' + lecture_url, ie=RbgTumIE.ie_key()))

        return self.playlist_result(lecture_urls, course_id, lecture_series_title)


Review comment (suggestion):
```suggestion
        course_id, hostname = self._match_valid_url(url).group('id', 'hostname')
```

Code after:
            'id': '2022/S/fpv',
        },
        'params': {
            'noplaylist': False,
        },
        'playlist_count': 13,
    }, {
        'url': 'https://live.rbg.tum.de/old/course/2022/W/set',
        'info_dict': {
            'title': 'SET FSMPIC',
            'id': '2022/W/set',
        },
        'params': {
            'noplaylist': False,
        },
        'playlist_count': 6,
    }, {
        'url': 'https://tum.live/old/course/2023/S/linalginfo',
        'only_matching': True,
    }, ]

    def _real_extract(self, url):
        course_id, hostname, year, term, slug = self._match_valid_url(url).group('id', 'hostname', 'year', 'term', 'slug')
        meta = self._download_json(
            f'https://{hostname}/api/courses/{slug}/', course_id, fatal=False,
            query={'year': year, 'term': term}) or {}
        lecture_series_title = meta.get('Name')
        lectures = [self.url_result(f'https://{hostname}/w/{slug}/{stream_id}', RbgTumIE)
                    for stream_id in traverse_obj(meta, ('Streams', ..., 'ID'))]

        if not lectures:
            webpage = self._download_webpage(url, course_id)
            lecture_series_title = remove_start(self._html_extract_title(webpage), 'TUM-Live | ')
            lectures = [self.url_result(f'https://{hostname}{lecture_path}', RbgTumIE)
                        for lecture_path in re.findall(r'href="(/w/[^/"]+/[^/"]+)"', webpage)]

        return self.playlist_result(lectures, course_id, lecture_series_title)


class RbgTumNewCourseIE(InfoExtractor):
    _VALID_URL = r'https://(?P<hostname>(?:live\.rbg\.tum\.de|tum\.live))/\?'
    _TESTS = [{
        'url': 'https://live.rbg.tum.de/?year=2022&term=S&slug=fpv&view=3',
        'info_dict': {
            'title': 'Funktionale Programmierung und Verifikation (IN0003)',
            'id': '2022/S/fpv',
        },
        'params': {
            'noplaylist': False,
        },
        'playlist_count': 13,