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

Code before:

class DacastIE(InfoExtractor):
    _VALID_URL = r'https?://iframe\.dacast\.com/vod/(?P<user_id>[\w-]+)/(?P<id>[\w-]+)'
    _TESTS = [{
        'url': 'https://iframe.dacast.com/vod/acae82153ef4d7a7344ae4eaa86af534/1c6143e3-5a06-371d-8695-19b96ea49090',
        'info_dict': {
            'id': '1c6143e3-5a06-371d-8695-19b96ea49090',
            'ext': 'mp4',
            'uploader_id': 'acae82153ef4d7a7344ae4eaa86af534',
            'title': '2_4||Adnexal mass characterisation: O-RADS US and MRI||N. Bharwani, London/UK',
            'thumbnail': 'https://universe-files.dacast.com/26137208-5858-65c1-5e9a-9d6b6bd2b6c2',
        },
        'params': {'skip_download': 'm3u8'},
    }]

    @staticmethod
    def _get_url_from_id(content_id):
        url_type = 'playlist' if '-playlist-' in content_id else 'vod'
        user_id, media_id = content_id.split(f'-{url_type}-')
        return f'https://iframe.dacast.com/{url_type}/{user_id}/{media_id}'

    @classmethod
    def _extract_embed_urls(cls, url, webpage):
        for content_id in re.findall(
                r'<script[^>]+\bsrc=["\']https://player\.dacast\.com/js/player\.js\?contentId=([\w-]+-vod-[\w-]+)["\']', webpage):
            yield DacastIE._get_url_from_id(content_id)

    def _real_extract(self, url):
        user_id, video_id = self._match_valid_url(url).group('user_id', 'id')
        query = {'contentId': f'{user_id}-vod-{video_id}', 'provider': 'universe'}
        info = self._download_json(
            'https://playback.dacast.com/content/info', video_id, query=query, fatal=False)
        access = self._download_json(
            'https://playback.dacast.com/content/access', video_id,
            note='Downloading access JSON', query=query, expected_status=403)

        error = access.get('error')
        if error in ('Broadcaster has been blocked', 'Content is offline'):
            raise ExtractorError(error, expected=True)
        elif error:
            raise ExtractorError(f'Dacast API says "{error}"')

        hls_url = access['hls']
        hls_aes = {}

        if 'DRM_EXT' in hls_url:
            self.report_drm(video_id)
        elif '/uspaes/' in hls_url:
            # From https://player.dacast.com/js/player.js
            ts = int(time.time())
            signature = hashlib.sha1(

Review comment (refactor):
These could be in a base class:

```suggestion
class DacastBaseIE(InfoExtractor):
    @staticmethod
    def _get_url_from_id(content_id):
        url_type = 'playlist' if '-playlist-' in content_id else 'vod'
        user_id, media_id = content_id.split(f'-{url_type}-')
        return f'https://iframe.dacast.com/{url_type}/{user_id}/{media_id}'

    @classmethod
    def _extract_embed_urls(cls, url, webpage):
        for content_id in re.findall(
                r'<script[^>]+\bsrc=["\']https://player\.dacast\.com/js/player\.js\?contentId=([\w-]+-(?:vod|playlist)-[\w-]+)["\']', webpage):
            yield cls._get_url_from_id(content_id)
```

Not mandatory, just a suggestion

Code after:


class DacastBaseIE(InfoExtractor):
    _URL_TYPE = None

    @classproperty
    def _VALID_URL(cls):
        return fr'https?://iframe\.dacast\.com/{cls._URL_TYPE}/(?P<user_id>[\w-]+)/(?P<id>[\w-]+)'

    @classproperty
    def _EMBED_REGEX(cls):
        return [rf'<iframe[^>]+\bsrc=["\'](?P<url>{cls._VALID_URL})']

    _API_INFO_URL = 'https://playback.dacast.com/content/info'

    @classmethod
    def _get_url_from_id(cls, content_id):
        user_id, media_id = content_id.split(f'-{cls._URL_TYPE}-')
        return f'https://iframe.dacast.com/{cls._URL_TYPE}/{user_id}/{media_id}'

    @classmethod
    def _extract_embed_urls(cls, url, webpage):
        yield from super()._extract_embed_urls(url, webpage)
        for content_id in re.findall(
                rf'<script[^>]+\bsrc=["\']https://player\.dacast\.com/js/player\.js\?contentId=([\w-]+-{cls._URL_TYPE}-[\w-]+)["\']', webpage):
            yield cls._get_url_from_id(content_id)


class DacastVODIE(DacastBaseIE):
    _URL_TYPE = 'vod'
    _TESTS = [{
        'url': 'https://iframe.dacast.com/vod/acae82153ef4d7a7344ae4eaa86af534/1c6143e3-5a06-371d-8695-19b96ea49090',
        'info_dict': {
            'id': '1c6143e3-5a06-371d-8695-19b96ea49090',
            'ext': 'mp4',
            'uploader_id': 'acae82153ef4d7a7344ae4eaa86af534',
            'title': '2_4||Adnexal mass characterisation: O-RADS US and MRI||N. Bharwani, London/UK',
            'thumbnail': 'https://universe-files.dacast.com/26137208-5858-65c1-5e9a-9d6b6bd2b6c2',
        },
        'params': {'skip_download': 'm3u8'},
    }]
    _WEBPAGE_TESTS = [{
        'url': 'https://www.dacast.com/support/knowledgebase/how-can-i-embed-a-video-on-my-website/',
        'info_dict': {
            'id': 'b6674869-f08a-23c5-1d7b-81f5309e1a90',
            'ext': 'mp4',
            'title': '4-HowToEmbedVideo.mp4',
            'uploader_id': '3b67c4a9-3886-4eb1-d0eb-39b23b14bef3',
            'thumbnail': 'https://universe-files.dacast.com/d26ab48f-a52a-8783-c42e-a90290ba06b6.png',
        },
        'params': {'skip_download': 'm3u8'},