]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/hrti.py
2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
7 from ..compat
import compat_HTTPError
18 class HRTiBaseIE(InfoExtractor
):
20 Base Information Extractor for Croatian Radiotelevision
21 video on demand site https://hrti.hrt.hr
22 Reverse engineered from the JavaScript app in app.min.js
24 _NETRC_MACHINE
= 'hrti'
28 _APP_PUBLICATION_ID
= 'all_in_one'
29 _API_URL
= 'http://clientapi.hrt.hr/client_api.php/config/identify/format/json'
31 def _initialize_api(self
):
33 'application_publication_id': self
._APP
_PUBLICATION
_ID
36 uuid
= self
._download
_json
(
37 self
._API
_URL
, None, note
='Downloading uuid',
38 errnote
='Unable to download uuid',
39 data
=json
.dumps(init_data
).encode('utf-8'))['uuid']
43 'application_publication_id': self
._APP
_PUBLICATION
_ID
,
44 'application_version': self
._APP
_VERSION
47 req
= sanitized_Request(self
._API
_URL
, data
=json
.dumps(app_data
).encode('utf-8'))
48 req
.get_method
= lambda: 'PUT'
50 resources
= self
._download
_json
(
51 req
, None, note
='Downloading session information',
52 errnote
='Unable to download session information')
54 self
._session
_id
= resources
['session_id']
56 modules
= resources
['modules']
58 self
._search
_url
= modules
['vod_catalog']['resources']['search']['uri'].format(
59 language
=self
._APP
_LANGUAGE
,
60 application_id
=self
._APP
_PUBLICATION
_ID
)
62 self
._login
_url
= (modules
['user']['resources']['login']['uri']
63 + '/format/json').format(session_id
=self
._session
_id
)
65 self
._logout
_url
= modules
['user']['resources']['logout']['uri']
68 username
, password
= self
._get
_login
_info
()
69 # TODO: figure out authentication with cookies
70 if username
is None or password
is None:
71 self
.raise_login_required()
79 auth_info
= self
._download
_json
(
80 self
._login
_url
, None, note
='Logging in', errnote
='Unable to log in',
81 data
=json
.dumps(auth_data
).encode('utf-8'))
82 except ExtractorError
as e
:
83 if isinstance(e
.cause
, compat_HTTPError
) and e
.cause
.code
== 406:
84 auth_info
= self
._parse
_json
(e
.cause
.read().encode('utf-8'), None)
88 error_message
= auth_info
.get('error', {}).get('message')
91 '%s said: %s' % (self
.IE_NAME
, error_message
),
94 self
._token
= auth_info
['secure_streaming_token']
96 def _real_initialize(self
):
97 self
._initialize
_api
()
101 class HRTiIE(HRTiBaseIE
):
102 _VALID_URL
= r
'''(?x)
104 hrti:(?P<short_id>[0-9]+)|
106 hrti\.hrt\.hr/(?:\#/)?video/show/(?P<id>[0-9]+)/(?P<display_id>[^/]+)?
110 'url': 'https://hrti.hrt.hr/#/video/show/2181385/republika-dokumentarna-serija-16-hd',
113 'display_id': 'republika-dokumentarna-serija-16-hd',
115 'title': 'REPUBLIKA, dokumentarna serija (1/6) (HD)',
116 'description': 'md5:48af85f620e8e0e1df4096270568544f',
119 'average_rating': int,
120 'episode_number': int,
121 'season_number': int,
124 'skip': 'Requires account credentials',
126 'url': 'https://hrti.hrt.hr/#/video/show/2181385/',
127 'only_matching': True,
129 'url': 'hrti:2181385',
130 'only_matching': True,
132 'url': 'https://hrti.hrt.hr/video/show/3873068/cuvar-dvorca-dramska-serija-14',
133 'only_matching': True,
136 def _real_extract(self
, url
):
137 mobj
= self
._match
_valid
_url
(url
)
138 video_id
= mobj
.group('short_id') or mobj
.group('id')
139 display_id
= mobj
.group('display_id') or video_id
141 video
= self
._download
_json
(
142 '%s/video_id/%s/format/json' % (self
._search
_url
, video_id
),
143 display_id
, 'Downloading video metadata JSON')['video'][0]
145 title_info
= video
['title']
146 title
= title_info
['title_long']
148 movie
= video
['video_assets']['movie'][0]
149 m3u8_url
= movie
['url'].format(TOKEN
=self
._token
)
150 formats
= self
._extract
_m
3u8_formats
(
151 m3u8_url
, display_id
, 'mp4', entry_protocol
='m3u8_native',
153 self
._sort
_formats
(formats
)
155 description
= clean_html(title_info
.get('summary_long'))
156 age_limit
= parse_age_limit(video
.get('parental_control', {}).get('rating'))
157 view_count
= int_or_none(video
.get('views'))
158 average_rating
= int_or_none(video
.get('user_rating'))
159 duration
= int_or_none(movie
.get('duration'))
163 'display_id': display_id
,
165 'description': description
,
166 'duration': duration
,
167 'view_count': view_count
,
168 'average_rating': average_rating
,
169 'age_limit': age_limit
,
174 class HRTiPlaylistIE(HRTiBaseIE
):
175 _VALID_URL
= r
'https?://hrti\.hrt\.hr/(?:#/)?video/list/category/(?P<id>[0-9]+)/(?P<display_id>[^/]+)?'
177 'url': 'https://hrti.hrt.hr/#/video/list/category/212/ekumena',
182 'playlist_mincount': 8,
183 'skip': 'Requires account credentials',
185 'url': 'https://hrti.hrt.hr/#/video/list/category/212/',
186 'only_matching': True,
188 'url': 'https://hrti.hrt.hr/video/list/category/212/ekumena',
189 'only_matching': True,
192 def _real_extract(self
, url
):
193 mobj
= self
._match
_valid
_url
(url
)
194 category_id
= mobj
.group('id')
195 display_id
= mobj
.group('display_id') or category_id
197 response
= self
._download
_json
(
198 '%s/category_id/%s/format/json' % (self
._search
_url
, category_id
),
199 display_id
, 'Downloading video metadata JSON')
202 response
, lambda x
: x
['video_listings'][0]['alternatives'][0]['list'],
203 list) or [video
['id'] for video
in response
.get('videos', []) if video
.get('id')]
205 entries
= [self
.url_result('hrti:%s' % video_id
) for video_id
in video_ids
]
207 return self
.playlist_result(entries
, category_id
, display_id
)