]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/videomore.py
3 from . common
import InfoExtractor
13 class VideomoreBaseIE ( InfoExtractor
):
14 _API_BASE_URL
= 'https://more.tv/api/v3/web/'
15 _VALID_URL_BASE
= r
'https?://(?:videomore\.ru|more\.tv)/'
17 def _download_page_data ( self
, display_id
):
18 return self
._ download
_ json
(
19 self
._ API
_ BASE
_U RL
+ 'PageData' , display_id
, query
={
20 'url' : '/' + display_id
,
21 })[ 'attributes' ][ 'response' ][ 'data' ]
23 def _track_url_result ( self
, track
):
24 track_vod
= track
[ 'trackVod' ]
25 video_url
= track_vod
. get ( 'playerLink' ) or track_vod
[ 'link' ]
26 return self
. url_result (
27 video_url
, VideomoreIE
. ie_key (), track_vod
. get ( 'hubId' ))
30 class VideomoreIE ( InfoExtractor
):
33 videomore:(?P<sid>\d+)$|
42 (?:player\.)?videomore\.ru|
43 siren\.more\.tv/player
44 )/[^/]*\?.*?\btrack_id=|
45 odysseus\.more.tv/player/(?P<partner_id>\d+)/
48 (?:[/?#&]|\.(?:xml|json)|$)
51 'url' : 'http://videomore.ru/kino_v_detalayah/5_sezon/367617' ,
52 'md5' : '44455a346edc0d509ac5b5a5b531dc35' ,
56 'title' : 'Кино в деталях 5 сезон В гостях Алексей Чумаков и Юлия Ковальчук' ,
57 'series' : 'Кино в деталях' ,
58 'episode' : 'В гостях Алексей Чумаков и Юлия Ковальчук' ,
59 'thumbnail' : r
're:^https?://.*\.jpg' ,
65 'skip' : 'The video is not available for viewing.' ,
67 'url' : 'http://videomore.ru/embed/259974' ,
71 'title' : 'Молодежка 2 сезон 40 серия' ,
72 'series' : 'Молодежка' ,
74 'episode' : '40 серия' ,
75 'thumbnail' : r
're:^https?://.*\.jpg' ,
81 'skip_download' : True ,
84 'url' : 'http://videomore.ru/molodezhka/sezon_promo/341073' ,
88 'title' : 'Промо Команда проиграла из-за Бакина?' ,
89 'episode' : 'Команда проиграла из-за Бакина?' ,
90 'thumbnail' : r
're:^https?://.*\.jpg' ,
96 'skip_download' : True ,
98 'skip' : 'The video is not available for viewing.' ,
100 'url' : 'http://videomore.ru/elki_3?track_id=364623' ,
101 'only_matching' : True ,
103 'url' : 'http://videomore.ru/embed/364623' ,
104 'only_matching' : True ,
106 'url' : 'http://videomore.ru/video/tracks/364623.xml' ,
107 'only_matching' : True ,
109 'url' : 'http://videomore.ru/video/tracks/364623.json' ,
110 'only_matching' : True ,
112 'url' : 'http://videomore.ru/video/tracks/158031/quotes/33248' ,
113 'only_matching' : True ,
115 'url' : 'videomore:367617' ,
116 'only_matching' : True ,
118 'url' : 'https://player.videomore.ru/?partner_id=97&track_id=736234&autoplay=0&userToken=' ,
119 'only_matching' : True ,
121 'url' : 'https://odysseus.more.tv/player/1788/352317' ,
122 'only_matching' : True ,
124 'url' : 'https://siren.more.tv/player/config?track_id=352317&partner_id=1788&user_token=' ,
125 'only_matching' : True ,
130 def _extract_url ( webpage
):
132 r
'<object[^>]+data=(["\' ]) https?
:// videomore\
. ru
/ player\
. swf
\? .* config
=( ?P
< url
> https?
:// videomore\
. ru
/( ?
:[ ^
/]+/)+ \d
+ \
. xml
).* \
1 ',
136 r' < iframe
[ ^
>]+ src
=([ \' "])(?P<url>https?://videomore\.ru/embed/\d+)',
140 return mobj.group('url')
142 def _real_extract(self, url):
143 mobj = self._match_valid_url(url)
144 video_id = mobj.group('sid') or mobj.group('id')
145 partner_id = mobj.group('partner_id') or parse_qs(url).get('partner_id', [None])[0] or '97'
147 item = self._download_json(
148 'https://siren.more.tv/player/config', video_id, query={
149 'partner_id': partner_id,
150 'track_id': video_id,
151 })['data']['playlist']['items'][0]
153 title = item.get('title')
154 series = item.get('project_name')
155 season = item.get('season_name')
156 episode = item.get('episode_name')
159 for v in (series, season, episode):
162 title = ' '.join(title)
164 streams = item.get('streams') or []
165 for protocol in ('DASH', 'HLS'):
166 stream_url = item.get(protocol.lower() + '_url')
168 streams.append( {'protocol': protocol, 'url': stream_url} )
171 for stream in streams:
172 stream_url = stream.get('url')
175 protocol = stream.get('protocol')
176 if protocol == 'DASH':
177 formats.extend(self._extract_mpd_formats(
178 stream_url, video_id, mpd_id='dash', fatal=False))
179 elif protocol == 'HLS':
180 formats.extend(self._extract_m3u8_formats(
181 stream_url, video_id, 'mp4', 'm3u8_native',
182 m3u8_id='hls', fatal=False))
183 elif protocol == 'MSS':
184 formats.extend(self._extract_ism_formats(
185 stream_url, video_id, ism_id='mss', fatal=False))
188 error = item.get('error')
190 if error in ('Данное видео недоступно для просмотра на территории этой страны', 'Данное видео доступно для просмотра только на территории России'):
191 self.raise_geo_restricted(countries=['RU'], metadata_available=True)
192 self.raise_no_formats(error, expected=True)
193 self._sort_formats(formats)
201 'thumbnail': item.get('thumbnail_url'),
202 'duration': int_or_none(item.get('duration')),
203 'view_count': int_or_none(item.get('views')),
204 'age_limit': int_or_none(item.get('min_age')),
209 class VideomoreVideoIE(VideomoreBaseIE):
210 IE_NAME = 'videomore:video'
211 _VALID_URL = VideomoreBaseIE._VALID_URL_BASE + r'(?P<id>(?:(?:[^/]+/) {2} )?[^/?#&]+)(?:/*|[?#&].*?)$'
213 # single video with og:video:iframe
214 'url': 'http://videomore.ru/elki_3',
220 'thumbnail': r're:^https?://.*\.jpg',
226 'skip_download': True,
228 'skip': 'Requires logging in',
230 # season single series with og:video:iframe
231 'url': 'http://videomore.ru/poslednii_ment/1_sezon/14_seriya',
235 'title': 'Последний мент 1 сезон 14 серия',
236 'series': 'Последний мент',
238 'episode': '14 серия',
239 'thumbnail': r're:^https?://.*\.jpg',
245 'skip_download': True,
248 'url': 'http://videomore.ru/sejchas_v_seti/serii_221-240/226_vypusk',
249 'only_matching': True,
251 # single video without og:video:iframe
252 'url': 'http://videomore.ru/marin_i_ego_druzya',
256 'title': '1 серия. Здравствуй, Аквавилль!',
257 'description': 'md5:c6003179538b5d353e7bcd5b1372b2d7',
258 'thumbnail': r're:^https?://.*\.jpg',
264 'skip_download': True,
266 'skip': 'redirects to https://more.tv/'
268 'url': 'https://videomore.ru/molodezhka/6_sezon/29_seriya?utm_so',
269 'only_matching': True,
271 'url': 'https://more.tv/poslednii_ment/1_sezon/14_seriya',
272 'only_matching': True,
276 def suitable(cls, url):
277 return False if VideomoreIE.suitable(url) else super(VideomoreVideoIE, cls).suitable(url)
279 def _real_extract(self, url):
280 display_id = self._match_id(url)
281 return self._track_url_result(self._download_page_data(display_id))
284 class VideomoreSeasonIE(VideomoreBaseIE):
285 IE_NAME = 'videomore:season'
286 _VALID_URL = VideomoreBaseIE._VALID_URL_BASE + r'(?!embed)(?P<id>[^/]+/[^/?#&]+)(?:/*|[?#&].*?)$'
288 'url': 'http://videomore.ru/molodezhka/film_o_filme',
290 'id': 'molodezhka/film_o_filme',
291 'title': 'Фильм о фильме',
293 'playlist_mincount': 3,
295 'url': 'http://videomore.ru/molodezhka/sezon_promo?utm_so',
296 'only_matching': True,
298 'url': 'https://more.tv/molodezhka/film_o_filme',
299 'only_matching': True,
303 def suitable(cls, url):
304 return (False if (VideomoreIE.suitable(url) or VideomoreVideoIE.suitable(url))
305 else super(VideomoreSeasonIE, cls).suitable(url))
307 def _real_extract(self, url):
308 display_id = self._match_id(url)
309 season = self._download_page_data(display_id)
310 season_id = compat_str(season['id'])
311 tracks = self._download_json(
312 self._API_BASE_URL + 'seasons/ %s /tracks' % season_id,
316 entries.append(self._track_url_result(track))
317 return self.playlist_result(entries, display_id, season.get('title'))