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

Code before:
        self._sort_formats(formats)
        return {
            'id': video_id,
            'display_id': display_id,
            'title': json_data['title'],
            'formats': formats,
            'duration': int_or_none(json_data.get('duration')),
            'average_rating': int_or_none(json_data.get('rating')),
            'description': str_or_none(json_data.get('description')),
            'alt_title': str_or_none(json_data.get('original_title')),
            'uploader': str_or_none(json_data.get('content_owner')),
            'age_limit': parse_age_limit(json_data.get('age_rating')),
            'release_date': unified_strdate(json_data.get('release_date')),
            'timestamp': unified_timestamp(json_data.get('release_date')),
            'thumbnail': url_or_none(json_data.get('image_url')),
            'series': try_get(json_data, lambda x: x['tvshow_details']['title'], str),
            'season': try_get(json_data, lambda x: x['season_details']['title'], str),
            'season_number': int_or_none(try_get(json_data, lambda x: x['season_details']['index'])),
            'episode_number': int_or_none(try_get(json_data, lambda x: x['index'])),
            'tags': try_get(json_data, lambda x: x['tags'], list)
        }


class Zee5SeriesIE(InfoExtractor):
    _VALID_URL = r'(?:https?://)(?:www\.)?zee5\.com/(?:global/)?(?:[^#/?]+/)?(?:(?:tvshows|kids)/[^#/?]+/)(?P<display_id>[^#/?]+)/(?P<id>[^#/?]+)/?(?:$|[?#])'
    _TEST = {
        'url': 'https://www.zee5.com/kids/kids-shows/krishna-balram/0-6-1871',
        'playlist_mincount': 43,
        'info_dict': {
            'id': '0-6-1871',
        },
    }

    def _entries(self, show_id):
        video_ids = []
        access_token_request = self._download_json(
            'https://useraction.zee5.com/token/platform_tokens.php?platform_name=web_app',
            show_id, note="Downloading access token")
        headers = {
            'X-Access-Token': access_token_request['token'],
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36',
            'Referer': 'https://www.zee5.com/',
        }
        showurl = 'https://gwapi.zee5.com/content/tvshow/{}?translation=en&country=IN'.format(show_id)

        seasonid = try_get(self._download_json(showurl, video_id=show_id, headers=headers), lambda x: x['season']['id'], str)
        nexturl = 'https://gwapi.zee5.com/content/tvshow/?season_id={}&type=episode&translation=en&country=IN&on_air=false&asset_subtype=tvshow&page=1&limit=10'.format(seasonid)
        while nexturl is not None:
            episodesjson = self._download_json(nexturl, video_id=show_id, headers=headers)
            episodes = try_get(episodesjson, lambda x: x['episode'], list)
            for episode in episodes:

Review comment (suggestion):
Add some more tests both here and in Zee5 that demonstrates the URLs with global/language. They can be added with `only_matching=True`. So no need of infodict

Code after:
            json_data,
            (lambda x: x['hls'][0], lambda x: x['video_details']['hls_url']),
            str)
        formats = self._extract_m3u8_formats(
            'https://zee5vodnd.akamaized.net' + m3u8_url.replace('/drm1/', '/hls1/') + token_request['video_token'],
            video_id, fatal=False)
        mpd_url = try_get(
            json_data,
            (lambda x: x['video'][0], lambda x: x['video_details']['url']),
            str)
        formats += self._extract_mpd_formats(
            'https://zee5vodnd.akamaized.net' + mpd_url + token_request['video_token'],
            video_id, fatal=False)

        self._sort_formats(formats)
        return {
            'id': video_id,
            'display_id': display_id,
            'title': json_data['title'],
            'formats': formats,
            'duration': int_or_none(json_data.get('duration')),
            'average_rating': int_or_none(json_data.get('rating')),
            'description': str_or_none(json_data.get('description')),
            'alt_title': str_or_none(json_data.get('original_title')),
            'uploader': str_or_none(json_data.get('content_owner')),
            'age_limit': parse_age_limit(json_data.get('age_rating')),
            'release_date': unified_strdate(json_data.get('release_date')),
            'timestamp': unified_timestamp(json_data.get('release_date')),
            'thumbnail': url_or_none(json_data.get('image_url')),
            'series': try_get(json_data, lambda x: x['tvshow_details']['title'], str),
            'season': try_get(json_data, lambda x: x['season_details']['title'], str),
            'season_number': int_or_none(try_get(json_data, lambda x: x['season_details']['index'])),
            'episode_number': int_or_none(try_get(json_data, lambda x: x['index'])),
            'tags': try_get(json_data, lambda x: x['tags'], list)
        }


class Zee5SeriesIE(InfoExtractor):
    IE_NAME = 'zee5:series'
    _VALID_URL = r'''(?x)
                     (?:
                        zee5:series:|
                        (?:https?://)(?:www\.)?zee5\.com/(?:[^#?]+/)?
                        (?:tvshows|kids)(?:/[^#/?]+){2}/
                     )
                     (?P<id>[^#/?]+)/?(?:$|[?#])
                     '''
    _TESTS = [{
        'url': 'https://www.zee5.com/kids/kids-shows/krishna-balram/0-6-1871',
        'playlist_mincount': 43,
        'info_dict': {