]> jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/voot.py
[extractor] Deprecate `_sort_formats`
[yt-dlp.git] / yt_dlp / extractor / voot.py
1 from .common import InfoExtractor
2 from ..compat import compat_str
3 from ..utils import (
4 ExtractorError,
5 int_or_none,
6 try_get,
7 unified_timestamp,
8 )
9
10
11 class VootIE(InfoExtractor):
12 _VALID_URL = r'''(?x)
13 (?:
14 voot:|
15 https?://(?:www\.)?voot\.com/?
16 (?:
17 movies?/[^/]+/|
18 (?:shows|kids)/(?:[^/]+/){4}
19 )
20 )
21 (?P<id>\d{3,})
22 '''
23 _GEO_COUNTRIES = ['IN']
24 _TESTS = [{
25 'url': 'https://www.voot.com/shows/ishq-ka-rang-safed/1/360558/is-this-the-end-of-kamini-/441353',
26 'info_dict': {
27 'id': '0_8ledb18o',
28 'ext': 'mp4',
29 'title': 'Ishq Ka Rang Safed - Season 01 - Episode 340',
30 'description': 'md5:06291fbbbc4dcbe21235c40c262507c1',
31 'timestamp': 1472162937,
32 'upload_date': '20160825',
33 'series': 'Ishq Ka Rang Safed',
34 'season_number': 1,
35 'episode': 'Is this the end of Kamini?',
36 'episode_number': 340,
37 'view_count': int,
38 'like_count': int,
39 },
40 'params': {
41 'skip_download': True,
42 },
43 'expected_warnings': ['Failed to download m3u8 information'],
44 }, {
45 'url': 'https://www.voot.com/kids/characters/mighty-cat-masked-niyander-e-/400478/school-bag-disappears/440925',
46 'only_matching': True,
47 }, {
48 'url': 'https://www.voot.com/movies/pandavas-5/424627',
49 'only_matching': True,
50 }, {
51 'url': 'https://www.voot.com/movie/fight-club/621842',
52 'only_matching': True,
53 }]
54
55 def _real_extract(self, url):
56 video_id = self._match_id(url)
57 media_info = self._download_json(
58 'https://wapi.voot.com/ws/ott/getMediaInfo.json', video_id,
59 query={
60 'platform': 'Web',
61 'pId': 2,
62 'mediaId': video_id,
63 })
64
65 status_code = try_get(media_info, lambda x: x['status']['code'], int)
66 if status_code != 0:
67 raise ExtractorError(media_info['status']['message'], expected=True)
68
69 media = media_info['assets']
70
71 entry_id = media['EntryId']
72 title = media['MediaName']
73 formats = self._extract_m3u8_formats(
74 'https://cdnapisec.kaltura.com/p/1982551/playManifest/pt/https/f/applehttp/t/web/e/' + entry_id,
75 video_id, 'mp4', m3u8_id='hls')
76
77 description, series, season_number, episode, episode_number = [None] * 5
78
79 for meta in try_get(media, lambda x: x['Metas'], list) or []:
80 key, value = meta.get('Key'), meta.get('Value')
81 if not key or not value:
82 continue
83 if key == 'ContentSynopsis':
84 description = value
85 elif key == 'RefSeriesTitle':
86 series = value
87 elif key == 'RefSeriesSeason':
88 season_number = int_or_none(value)
89 elif key == 'EpisodeMainTitle':
90 episode = value
91 elif key == 'EpisodeNo':
92 episode_number = int_or_none(value)
93 return {
94 'extractor_key': 'Kaltura',
95 'id': entry_id,
96 'title': title,
97 'description': description,
98 'series': series,
99 'season_number': season_number,
100 'episode': episode,
101 'episode_number': episode_number,
102 'timestamp': unified_timestamp(media.get('CreationDate')),
103 'duration': int_or_none(media.get('Duration')),
104 'view_count': int_or_none(media.get('ViewCounter')),
105 'like_count': int_or_none(media.get('like_counter')),
106 'formats': formats,
107 }
108
109
110 class VootSeriesIE(InfoExtractor):
111 _VALID_URL = r'https?://(?:www\.)?voot\.com/shows/[^/]+/(?P<id>\d{3,})'
112 _TESTS = [{
113 'url': 'https://www.voot.com/shows/chakravartin-ashoka-samrat/100002',
114 'playlist_mincount': 442,
115 'info_dict': {
116 'id': '100002',
117 },
118 }, {
119 'url': 'https://www.voot.com/shows/ishq-ka-rang-safed/100003',
120 'playlist_mincount': 341,
121 'info_dict': {
122 'id': '100003',
123 },
124 }]
125 _SHOW_API = 'https://psapi.voot.com/media/voot/v1/voot-web/content/generic/season-by-show?sort=season%3Aasc&id={}&responseType=common'
126 _SEASON_API = 'https://psapi.voot.com/media/voot/v1/voot-web/content/generic/series-wise-episode?sort=episode%3Aasc&id={}&responseType=common&page={:d}'
127
128 def _entries(self, show_id):
129 show_json = self._download_json(self._SHOW_API.format(show_id), video_id=show_id)
130 for season in show_json.get('result', []):
131 page_num = 1
132 season_id = try_get(season, lambda x: x['id'], compat_str)
133 season_json = self._download_json(self._SEASON_API.format(season_id, page_num),
134 video_id=season_id,
135 note='Downloading JSON metadata page %d' % page_num)
136 episodes_json = season_json.get('result', [])
137 while episodes_json:
138 page_num += 1
139 for episode in episodes_json:
140 video_id = episode.get('id')
141 yield self.url_result(
142 'voot:%s' % video_id, ie=VootIE.ie_key(), video_id=video_id)
143 episodes_json = self._download_json(self._SEASON_API.format(season_id, page_num),
144 video_id=season_id,
145 note='Downloading JSON metadata page %d' % page_num)['result']
146
147 def _real_extract(self, url):
148 show_id = self._match_id(url)
149 return self.playlist_result(self._entries(show_id), playlist_id=show_id)