diff --git a/yt_dlp/extractor/extractors.py b/yt_dlp/extractor/extractors.py index 3dc2c10f8..d80eafaf9 100644 --- a/yt_dlp/extractor/extractors.py +++ b/yt_dlp/extractor/extractors.py @@ -1668,5 +1668,6 @@ from .zdf import ZDFIE, ZDFChannelIE from .zhihu import ZhihuIE from .zingmp3 import ZingMp3IE from .zee5 import Zee5IE +from .zee5 import Zee5SeriesIE from .zoom import ZoomIE from .zype import ZypeIE diff --git a/yt_dlp/extractor/zee5.py b/yt_dlp/extractor/zee5.py index a558e9d78..34861f0d2 100644 --- a/yt_dlp/extractor/zee5.py +++ b/yt_dlp/extractor/zee5.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import re from .common import InfoExtractor +from ..compat import compat_str from ..utils import ( int_or_none, parse_age_limit, @@ -16,24 +17,34 @@ from ..utils import ( class Zee5IE(InfoExtractor): - _VALID_URL = r'(?:zee5:|https?://(?:www\.)?zee5\.com/[^#?]*/(?P[^#?]+)/)(?P[^#?/]+)(?:$|[?#])' + _VALID_URL = r'''(?x) + (?: + zee5:| + (?:https?://)(?:www\.)?zee5\.com/(?:[^#?]+/)? + (?: + (?:tvshows|kids)(?:/[^#/?]+){3} + |movies/[^#/?]+ + )/(?P[^#/?]+)/ + ) + (?P[^#/?]+)/?(?:$|[?#]) + ''' _TESTS = [{ 'url': 'https://www.zee5.com/movies/details/krishna-the-birth/0-0-63098', 'info_dict': { - "id": "0-0-63098", - "ext": "m3u8", - "display_id": "krishna-the-birth", - "title": "Krishna - The Birth", - "duration": 4368, - "average_rating": 4, - "description": str, - "alt_title": "Krishna - The Birth", - "uploader": "Zee Entertainment Enterprises Ltd", - "release_date": "20060101", - "upload_date": "20060101", - "timestamp": 1136073600, - "thumbnail": "https://akamaividz.zee5.com/resources/0-0-63098/list/270x152/0063098_list_80888170.jpg", - "tags": list + 'id': '0-0-63098', + 'ext': 'mp4', + 'display_id': 'krishna-the-birth', + 'title': 'Krishna - The Birth', + 'duration': 4368, + 'average_rating': 4, + 'description': str, + 'alt_title': 'Krishna - The Birth', + 'uploader': 'Zee Entertainment Enterprises Ltd', + 'release_date': '20060101', + 'upload_date': '20060101', + 'timestamp': 1136073600, + 'thumbnail': 'https://akamaividz.zee5.com/resources/0-0-63098/list/270x152/0063098_list_80888170.jpg', + 'tags': list }, 'params': { 'format': 'bv', @@ -41,23 +52,23 @@ class Zee5IE(InfoExtractor): }, { 'url': 'https://zee5.com/tvshows/details/krishna-balram/0-6-1871/episode-1-the-test-of-bramha/0-1-233402', 'info_dict': { - "id": "0-1-233402", - 'ext': 'm3u8', - "display_id": "episode-1-the-test-of-bramha", - "title": "Episode 1 - The Test Of Bramha", - "duration": 1336, - "average_rating": 4, - "description": str, - "alt_title": "Episode 1 - The Test Of Bramha", - "uploader": "Green Gold", - "release_date": "20090101", - "upload_date": "20090101", - "timestamp": 1230768000, - "thumbnail": "https://akamaividz.zee5.com/resources/0-1-233402/list/270x152/01233402_list.jpg", - "series": "Krishna Balram", - "season_number": 1, - "episode_number": 1, - "tags": list, + 'id': '0-1-233402', + 'ext': 'mp4', + 'display_id': 'episode-1-the-test-of-bramha', + 'title': 'Episode 1 - The Test Of Bramha', + 'duration': 1336, + 'average_rating': 4, + 'description': str, + 'alt_title': 'Episode 1 - The Test Of Bramha', + 'uploader': 'Green Gold', + 'release_date': '20090101', + 'upload_date': '20090101', + 'timestamp': 1230768000, + 'thumbnail': 'https://akamaividz.zee5.com/resources/0-1-233402/list/270x152/01233402_list.jpg', + 'series': 'Krishna Balram', + 'season_number': 1, + 'episode_number': 1, + 'tags': list, }, 'params': { 'format': 'bv', @@ -65,16 +76,19 @@ class Zee5IE(InfoExtractor): }, { 'url': 'https://www.zee5.com/hi/tvshows/details/kundali-bhagya/0-6-366/kundali-bhagya-march-08-2021/0-1-manual_7g9jv1os7730?country=IN', 'only_matching': True + }, { + 'url': 'https://www.zee5.com/global/hi/tvshows/details/kundali-bhagya/0-6-366/kundali-bhagya-march-08-2021/0-1-manual_7g9jv1os7730', + 'only_matching': True }] def _real_extract(self, url): video_id, display_id = re.match(self._VALID_URL, url).group('id', 'display_id') access_token_request = self._download_json( 'https://useraction.zee5.com/token/platform_tokens.php?platform_name=web_app', - video_id, note="Downloading access token") + video_id, note='Downloading access token') token_request = self._download_json( 'https://useraction.zee5.com/tokennd', - video_id, note="Downloading video token") + video_id, note='Downloading video token') json_data = self._download_json( 'https://gwapi.zee5.com/content/details/{}?translation=en&country=IN'.format(video_id), video_id, headers={'X-Access-Token': access_token_request['token']}) @@ -114,3 +128,78 @@ class Zee5IE(InfoExtractor): '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[^#/?]+)/?(?:$|[?#]) + ''' + _TESTS = [{ + 'url': 'https://www.zee5.com/kids/kids-shows/krishna-balram/0-6-1871', + 'playlist_mincount': 43, + 'info_dict': { + 'id': '0-6-1871', + }, + }, { + 'url': 'https://www.zee5.com/tvshows/details/bhabi-ji-ghar-par-hai/0-6-199', + 'playlist_mincount': 1500, + 'info_dict': { + 'id': '0-6-199', + }, + }, { + 'url': 'https://www.zee5.com/tvshows/details/agent-raghav-crime-branch/0-6-965', + 'playlist_mincount': 25, + 'info_dict': { + 'id': '0-6-965', + }, + }, { + 'url': 'https://www.zee5.com/ta/tvshows/details/nagabhairavi/0-6-3201', + 'playlist_mincount': 3, + 'info_dict': { + 'id': '0-6-3201', + }, + }, { + 'url': 'https://www.zee5.com/global/hi/tvshows/details/khwaabon-ki-zamin-par/0-6-270', + 'playlist_mincount': 150, + 'info_dict': { + 'id': '0-6-270', + }, + } + ] + + def _entries(self, show_id): + 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'], + 'Referer': 'https://www.zee5.com/', + } + show_url = 'https://gwapi.zee5.com/content/tvshow/{}?translation=en&country=IN'.format(show_id) + + page_num = 0 + show_json = self._download_json(show_url, video_id=show_id, headers=headers) + for season in show_json.get('seasons') or []: + season_id = try_get(season, lambda x: x['id'], compat_str) + next_url = 'https://gwapi.zee5.com/content/tvshow/?season_id={}&type=episode&translation=en&country=IN&on_air=false&asset_subtype=tvshow&page=1&limit=100'.format(season_id) + while next_url: + page_num += 1 + episodes_json = self._download_json( + next_url, video_id=show_id, headers=headers, + note='Downloading JSON metadata page %d' % page_num) + for episode in try_get(episodes_json, lambda x: x['episode'], list) or []: + video_id = episode.get('id') + yield self.url_result( + 'zee5:%s' % video_id, + ie=Zee5IE.ie_key(), video_id=video_id) + next_url = url_or_none(episodes_json.get('next_episode_api')) + + def _real_extract(self, url): + show_id = self._match_id(url) + return self.playlist_result(self._entries(show_id), playlist_id=show_id)