2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
7 from ..compat
import compat_str
20 class Zee5IE(InfoExtractor
):
24 https?://(?:www\.)?zee5\.com/(?:[^#?]+/)?
26 (?:tvshows|kids|zee5originals)(?:/[^#/?]+){3}
28 )/(?P<display_id>[^#/?]+)/
30 (?P<id>[^#/?]+)/?(?:$|[?#])
33 'url': 'https://www.zee5.com/movies/details/krishna-the-birth/0-0-63098',
37 'display_id': 'krishna-the-birth',
38 'title': 'Krishna - The Birth',
41 'description': compat_str
,
42 'alt_title': 'Krishna - The Birth',
43 'uploader': 'Zee Entertainment Enterprises Ltd',
44 'release_date': '20060101',
45 'upload_date': '20060101',
46 'timestamp': 1136073600,
47 'thumbnail': 'https://akamaividz.zee5.com/resources/0-0-63098/list/270x152/0063098_list_80888170.jpg',
54 'url': 'https://zee5.com/tvshows/details/krishna-balram/0-6-1871/episode-1-the-test-of-bramha/0-1-233402',
58 'display_id': 'episode-1-the-test-of-bramha',
59 'title': 'Episode 1 - The Test Of Bramha',
62 'description': compat_str
,
63 'alt_title': 'Episode 1 - The Test Of Bramha',
64 'uploader': 'Zee Entertainment Enterprises Ltd',
65 'release_date': '20090101',
66 'upload_date': '20090101',
67 'timestamp': 1230768000,
68 'thumbnail': 'https://akamaividz.zee5.com/resources/0-1-233402/list/270x152/01233402_list.jpg',
69 'series': 'Krishna Balram',
78 'url': 'https://www.zee5.com/hi/tvshows/details/kundali-bhagya/0-6-366/kundali-bhagya-march-08-2021/0-1-manual_7g9jv1os7730?country=IN',
81 'url': 'https://www.zee5.com/global/hi/tvshows/details/kundali-bhagya/0-6-366/kundali-bhagya-march-08-2021/0-1-manual_7g9jv1os7730',
84 _DETAIL_API_URL
= 'https://spapi.zee5.com/singlePlayback/getDetails?content_id={}&device_id={}&platform_name=desktop_web&country=IN&check_parental_control=false'
85 _DEVICE_ID
= 'iIxsxYf40cqO3koIkwzKHZhnJzHN13zb'
87 _LOGIN_HINT
= 'Use "--username <mobile_number>" to login using otp or "--username token" and "--password <user_token>" to login using user token.'
88 _NETRC_MACHINE
= 'zee5'
91 username
, password
= self
._get
_login
_info
()
93 if len(username
) == 10 and username
.isdigit() and self
._USER
_TOKEN
is None:
95 otp_request_json
= self
._download
_json
('https://b2bapi.zee5.com/device/sendotp_v1.php?phoneno=91{}'.format(username
),
96 None, note
='Sending OTP')
97 if otp_request_json
['code'] == 0:
98 self
.to_screen(otp_request_json
['message'])
100 raise ExtractorError(otp_request_json
['message'], expected
=True)
101 otp_code
= self
._get
_tfa
_info
('OTP')
102 otp_verify_json
= self
._download
_json
('https://b2bapi.zee5.com/device/verifyotp_v1.php?phoneno=91{}&otp={}&guest_token={}&platform=web'.format(username
, otp_code
, self
._DEVICE
_ID
),
103 None, note
='Verifying OTP', fatal
=False)
104 if not otp_verify_json
:
105 raise ExtractorError('Unable to verify OTP.', expected
=True)
106 self
._USER
_TOKEN
= otp_verify_json
.get('token')
107 if not self
._USER
_TOKEN
:
108 raise ExtractorError(otp_request_json
['message'], expected
=True)
109 elif username
.lower() == 'token' and len(password
) > 1198:
110 self
._USER
_TOKEN
= password
112 def _real_initialize(self
):
115 def _real_extract(self
, url
):
116 video_id
, display_id
= self
._match
_valid
_url
(url
).group('id', 'display_id')
117 access_token_request
= self
._download
_json
(
118 'https://useraction.zee5.com/token/platform_tokens.php?platform_name=web_app',
119 video_id
, note
='Downloading access token')
121 'x-access-token': access_token_request
['token']
124 data
['Authorization'] = 'bearer %s' % self
._USER
_TOKEN
126 data
['X-Z5-Guest-Token'] = self
._DEVICE
_ID
128 json_data
= self
._download
_json
(
129 self
._DETAIL
_API
_URL
.format(video_id
, self
._DEVICE
_ID
),
130 video_id
, headers
={'content-type': 'application/json'}
, data
=json
.dumps(data
).encode('utf-8'))
131 asset_data
= json_data
['assetDetails']
132 show_data
= json_data
.get('showDetails', {})
133 if 'premium' in asset_data
['business_type']:
134 raise ExtractorError('Premium content is DRM protected.', expected
=True)
135 if not asset_data
.get('hls_url'):
136 self
.raise_login_required(self
._LOGIN
_HINT
, metadata_available
=True, method
=None)
137 formats
, m3u8_subs
= self
._extract
_m
3u8_formats
_and
_subtitles
(asset_data
['hls_url'], video_id
, 'mp4', fatal
=False)
138 self
._sort
_formats
(formats
)
141 for sub
in asset_data
.get('subtitle_url', []):
142 sub_url
= sub
.get('url')
145 subtitles
.setdefault(sub
.get('language', 'en'), []).append({
146 'url': self
._proto
_relative
_url
(sub_url
),
148 subtitles
= self
._merge
_subtitles
(subtitles
, m3u8_subs
)
151 'display_id': display_id
,
152 'title': asset_data
['title'],
154 'subtitles': subtitles
,
155 'duration': int_or_none(asset_data
.get('duration')),
156 'average_rating': int_or_none(asset_data
.get('rating')),
157 'description': str_or_none(asset_data
.get('description')),
158 'alt_title': str_or_none(asset_data
.get('original_title')),
159 'uploader': str_or_none(asset_data
.get('content_owner')),
160 'age_limit': parse_age_limit(asset_data
.get('age_rating')),
161 'release_date': unified_strdate(asset_data
.get('release_date')),
162 'timestamp': unified_timestamp(asset_data
.get('release_date')),
163 'thumbnail': url_or_none(asset_data
.get('image_url')),
164 'series': str_or_none(asset_data
.get('tvshow_name')),
165 'season': try_get(show_data
, lambda x
: x
['seasons']['title'], str),
166 'season_number': int_or_none(try_get(show_data
, lambda x
: x
['seasons'][0]['orderid'])),
167 'episode_number': int_or_none(try_get(asset_data
, lambda x
: x
['orderid'])),
168 'tags': try_get(asset_data
, lambda x
: x
['tags'], list)
172 class Zee5SeriesIE(InfoExtractor
):
173 IE_NAME
= 'zee5:series'
174 _VALID_URL
= r
'''(?x)
177 https?://(?:www\.)?zee5\.com/(?:[^#?]+/)?
178 (?:tvshows|kids|zee5originals)(?:/[^#/?]+){2}/
180 (?P<id>[^#/?]+)(?:/episodes)?/?(?:$|[?#])
183 'url': 'https://www.zee5.com/kids/kids-shows/krishna-balram/0-6-1871',
184 'playlist_mincount': 43,
189 'url': 'https://www.zee5.com/tvshows/details/bhabi-ji-ghar-par-hai/0-6-199',
190 'playlist_mincount': 1500,
195 'url': 'https://www.zee5.com/tvshows/details/agent-raghav-crime-branch/0-6-965',
196 'playlist_mincount': 24,
201 'url': 'https://www.zee5.com/ta/tvshows/details/nagabhairavi/0-6-3201',
202 'playlist_mincount': 3,
207 'url': 'https://www.zee5.com/global/hi/tvshows/details/khwaabon-ki-zamin-par/0-6-270',
208 'playlist_mincount': 150,
213 'url': 'https://www.zee5.com/tvshows/details/chala-hawa-yeu-dya-ladies-zindabaad/0-6-2943/episodes',
214 'only_matching': True,
217 def _entries(self
, show_id
):
218 access_token_request
= self
._download
_json
(
219 'https://useraction.zee5.com/token/platform_tokens.php?platform_name=web_app',
220 show_id
, note
='Downloading access token')
222 'X-Access-Token': access_token_request
['token'],
223 'Referer': 'https://www.zee5.com/',
225 show_url
= 'https://gwapi.zee5.com/content/tvshow/{}?translation=en&country=IN'.format(show_id
)
228 show_json
= self
._download
_json
(show_url
, video_id
=show_id
, headers
=headers
)
229 for season
in show_json
.get('seasons') or []:
230 season_id
= try_get(season
, lambda x
: x
['id'], compat_str
)
231 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
)
234 episodes_json
= self
._download
_json
(
235 next_url
, video_id
=show_id
, headers
=headers
,
236 note
='Downloading JSON metadata page %d' % page_num
)
237 for episode
in try_get(episodes_json
, lambda x
: x
['episode'], list) or []:
238 video_id
= episode
.get('id')
239 yield self
.url_result(
240 'zee5:%s' % video_id
,
241 ie
=Zee5IE
.ie_key(), video_id
=video_id
)
242 next_url
= url_or_none(episodes_json
.get('next_episode_api'))
244 def _real_extract(self
, url
):
245 show_id
= self
._match
_id
(url
)
246 return self
.playlist_result(self
._entries
(show_id
), playlist_id
=show_id
)