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

Code before:
                    track_obj.update({
                        'app': m_obj.group('app'),
                        'ext': m_obj.group('ext'),
                        'play_path': m_obj.group('ext') + ':' + m_obj.group('playpath'),
                        'rtmp_live': True,
                        'preference': -2,
                    })
                formats.append(track_obj)

        return {
            'id': video_id,
            'formats': formats,
            'title': video.get('title'),
            'series': video.get('seriestitle'),
            'season_id': video.get('series'),
            'creator': traverse_obj(video, ('creators', 'creator')),
            'timestamp': parse_iso8601(video.get('start')),
            'thumbnail': traverse_obj(video, ('attachments', 'attachment', ..., 'url'), get_all=False),
        }


class OpencastIE(OpencastBaseIE):
    _VALID_URL = rf'''(?x)
                    https?://(?P<host>{OpencastBaseIE._INSTANCES_RE})/paella/ui/watch.html\?(?:[^#]+&)?
                    id=(?P<id>{OpencastBaseIE._UUID_RE})
                    '''

    _API_BASE = 'https://%s/search/episode.json?id=%s'

    _TESTS = [
        {
            'url': 'https://oc-video1.ruhr-uni-bochum.de/paella/ui/watch.html?id=ed063cd5-72c8-46b5-a60a-569243edcea8',
            'md5': '554c8e99a90f7be7e874619fcf2a3bc9',
            'info_dict': {
                'id': 'ed063cd5-72c8-46b5-a60a-569243edcea8',
                'ext': 'mp4',
                'title': '11 - Kryptographie - 24.11.2015',
                'thumbnail': r're:^https?://.*\.jpg$',
                'timestamp': 1606208400,
                'upload_date': '20201124',
                'season_id': 'cf68a4a1-36b1-4a53-a6ba-61af5705a0d0',
                'series': 'Kryptographie - WiSe 15/16',
                'creator': 'Alexander May',
            },
        }
    ]

    def _real_extract(self, url):
        host, video_id = self._match_valid_url(url).group('host', 'id')
        return self._parse_mediapackage(
            self._call_api(host, video_id)['search-results']['result']['mediapackage'])

Review comment (suggestion):
```suggestion
    _VALID_URL = rf'''(?x)
        https?://(?P<host>{OpencastBaseIE._INSTANCES_RE})/paella/ui/watch.html\?
        (?:[^#]+&)?id=(?P<id>{OpencastBaseIE._UUID_RE})'''
```

Code after:
                    track_obj.update({
                        'app': m_obj.group('app'),
                        'ext': m_obj.group('ext'),
                        'play_path': m_obj.group('ext') + ':' + m_obj.group('playpath'),
                        'rtmp_live': True,
                        'preference': -2,
                    })
                formats.append(track_obj)

        return {
            'id': video_id,
            'formats': formats,
            'title': video.get('title'),
            'series': video.get('seriestitle'),
            'season_id': video.get('series'),
            'creator': traverse_obj(video, ('creators', 'creator')),
            'timestamp': parse_iso8601(video.get('start')),
            'thumbnail': traverse_obj(video, ('attachments', 'attachment', ..., 'url'), get_all=False),
        }


class OpencastIE(OpencastBaseIE):
    _VALID_URL = rf'''(?x)
        https?://(?P<host>{OpencastBaseIE._INSTANCES_RE})/paella/ui/watch\.html\?
        (?:[^#]+&)?id=(?P<id>{OpencastBaseIE._UUID_RE})'''

    _API_BASE = 'https://%s/search/episode.json?id=%s'

    _TESTS = [
        {
            'url': 'https://oc-video1.ruhr-uni-bochum.de/paella/ui/watch.html?id=ed063cd5-72c8-46b5-a60a-569243edcea8',
            'md5': '554c8e99a90f7be7e874619fcf2a3bc9',
            'info_dict': {
                'id': 'ed063cd5-72c8-46b5-a60a-569243edcea8',
                'ext': 'mp4',
                'title': '11 - Kryptographie - 24.11.2015',
                'thumbnail': r're:^https?://.*\.jpg$',
                'timestamp': 1606208400,
                'upload_date': '20201124',
                'season_id': 'cf68a4a1-36b1-4a53-a6ba-61af5705a0d0',
                'series': 'Kryptographie - WiSe 15/16',
                'creator': 'Alexander May',
            },
        }
    ]

    def _real_extract(self, url):
        host, video_id = self._match_valid_url(url).group('host', 'id')
        return self._parse_mediapackage(
            self._call_api(host, video_id)['search-results']['result']['mediapackage'])