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

Code before:
        'url': 'https://subsplash.com/prophecywatchers/media/ms/+n42mr48',
        'info_dict': {
            'id': 'n42mr48',
            'title': 'Road to Zion Series',
        },
        'playlist_mincount': 13,
    }, {
        'url': 'https://subsplash.com/prophecywatchers/media/ms/+918b9f6',
        'only_matching': True,
    }]

    def _entries(self, series_id, headers, page):
        data = self._download_json(
            'https://core.subsplash.com/media/v1/media-items', series_id, headers=headers,
            query={
                'filter[broadcast.status|broadcast.status]': 'null|on-demand',
                'filter[media_series]': series_id,
                'filter[status]': 'published',
                'include': 'images,audio.audio-outputs,audio.video,video.video-outputs,video.playlists,document',
                'page[number]': page + 1,
                'page[size]': self._PAGE_SIZE,
                'sort': '-position',
            }, note=f'Downloading page {page + 1}')

        entries = traverse_obj(data, ('_embedded', 'media-items', lambda _, v: v['short_code']))
        for entry in entries:
            info = self._extract_video(entry, entry.get('id'))
            yield {
                **info,
                'webpage_url': f'https://subspla.sh/{entry["short_code"]}',
                'extractor_key': SubsplashIE.ie_key(),
                'extractor': SubsplashIE.IE_NAME,
            }

    def _real_extract(self, url):
        display_id = self._match_id(url)
        headers = self._get_headers(url, display_id)

        data = self._download_json(
            'https://core.subsplash.com/media/v1/media-series', display_id, headers=headers,
            query={'filter[short_code]': display_id})
        series_data = traverse_obj(data, ('_embedded', 'media-series', 0, {
            'id': ('id', {str}),
            'title': ('title', {str}),
            'count': ('media_items_count', {int}),
        }))
        total_pages = math.ceil(series_data['count'] / self._PAGE_SIZE)

        return self.playlist_result(
            InAdvancePagedList(functools.partial(self._entries, series_data['id'], headers), total_pages, self._PAGE_SIZE),
            display_id, series_data['title'])

Review comment (suggestion):
```suggestion
        for entry in traverse_obj(data, ('_embedded', 'media-items', lambda _, v: v['short_code'])):
```

Code after:
        return self._extract_video(traverse_obj(data, ('_embedded', 'media-items', 0)), video_id)


class SubsplashPlaylistIE(SubsplashBaseIE):
    IE_NAME = 'subsplash:playlist'
    _VALID_URL = r'https?://(?:www\.)?subsplash\.com/[^/?#]+/(?:our-videos|media)/ms/\+(?P<id>\w+)'
    _PAGE_SIZE = 15
    _TESTS = [{
        'url': 'https://subsplash.com/skywatchtv/our-videos/ms/+dbyjzp8',
        'info_dict': {
            'id': 'dbyjzp8',
            'title': 'Five in Ten',
        },
        'playlist_mincount': 11,
    }, {
        'url': 'https://subsplash.com/prophecywatchers/media/ms/+n42mr48',
        'info_dict': {
            'id': 'n42mr48',
            'title': 'Road to Zion Series',
        },
        'playlist_mincount': 13,
    }, {
        'url': 'https://subsplash.com/prophecywatchers/media/ms/+918b9f6',
        'only_matching': True,
    }]

    def _entries(self, series_id, headers, page):
        data = self._download_json(
            'https://core.subsplash.com/media/v1/media-items', series_id, headers=headers,
            query={
                'filter[broadcast.status|broadcast.status]': 'null|on-demand',
                'filter[media_series]': series_id,
                'filter[status]': 'published',
                'include': 'images,audio.audio-outputs,audio.video,video.video-outputs,video.playlists,document',
                'page[number]': page + 1,
                'page[size]': self._PAGE_SIZE,
                'sort': '-position',
            }, note=f'Downloading page {page + 1}')

        for entry in traverse_obj(data, ('_embedded', 'media-items', lambda _, v: v['short_code'])):
            entry_id = entry['short_code']
            info = self._extract_video(entry, entry_id)
            yield {
                **info,
                'webpage_url': f'https://subspla.sh/{entry_id}',
                'extractor_key': SubsplashIE.ie_key(),
                'extractor': SubsplashIE.IE_NAME,
            }

    def _real_extract(self, url):
        display_id = self._match_id(url)