2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
16 class HRTiIE(InfoExtractor
):
18 Information Extractor for Croatian Radiotelevision video on demand site
20 Reverse engineered from the JavaScript app in app.min.js
22 _NETRC_MACHINE
= 'hrti'
26 APP_PUBLICATION_ID
= 'all_in_one'
28 _VALID_URL
= r
'https?://hrti.hrt.hr/#/video/show/(?P<id>[0-9]+)/(?P<name>(\w|-)+)?'
30 'url': 'https://hrti.hrt.hr/#/video/show/2181385/republika-dokumentarna-serija-16-hd',
34 'name': 'REPUBLIKA, dokumentarna serija (4_6)-2251938',
36 'skip': 'Requires login'
39 def _initialize_api(self
):
40 '''Initializes the API and obtains the required urls'''
41 api_url
= 'http://clientapi.hrt.hr/client_api.php/config/identify/format/json'
42 app_data
= json
.dumps({
43 'application_publication_id': HRTiIE
.APP_PUBLICATION_ID
45 self
.uuid
= self
._download
_json
(api_url
, None, note
='Getting UUID',
46 errnote
='Unable to obtain an UUID',
47 data
=app_data
)['uuid']
49 app_data
= json
.dumps({
51 'application_publication_id': HRTiIE
.APP_PUBLICATION_ID
,
52 'screen_height': 1080,
55 'os_version': 'NT 4.0',
56 'device_model_string_id': 'chrome 42.0.2311.135',
57 'application_version': HRTiIE
.APP_VERSION
60 req
= sanitized_Request(api_url
, data
=app_data
)
61 req
.get_method
= lambda: 'PUT'
63 resources
= self
._download
_json
(
64 req
, None, note
='Getting API endpoint and session information',
65 errnote
='Unable to get endpoint and session information',
66 headers
={'Content-type': 'application/json'}
)
68 self
.session_id
= resources
['session_id']
69 modules
= resources
['modules']
71 self
.search_url
= modules
['vod_catalog']['resources']['search']['uri']
72 self
.search_url
= self
.search_url
.format(
73 language
=HRTiIE
.APP_LANGUAGE
,
74 application_id
=HRTiIE
.APP_PUBLICATION_ID
)
76 self
.login_url
= modules
['user']['resources']['login']['uri']
77 self
.login_url
= self
.login_url
.format(session_id
=self
.session_id
)
78 self
.login_url
+= '/format/json'
80 self
.logout_url
= modules
['user']['resources']['logout']['uri']
83 '''Performs a login to the webservice'''
84 (username
, password
) = self
._get
_login
_info
()
86 if username
is None or password
is None:
87 self
.raise_login_required()
89 auth_data
= json
.dumps({
94 auth_info
= self
._download
_json
(
95 self
.login_url
, None, note
='Authenticating',
96 errnote
='Unable to log in', data
=auth_data
)
97 except ExtractorError
as ee
:
98 if isinstance(ee
.cause
, compat_HTTPError
) and ee
.cause
.code
== 406:
99 raise ExtractorError('Unable to login, ' +
100 'incorrect username and/or password')
103 self
.token
= auth_info
['secure_streaming_token']
104 self
.access_token
= auth_info
['session_token']
106 self
.logout_url
= self
.logout_url
.format(session_id
=self
.session_id
,
107 access_token
=self
.access_token
)
108 self
.logout_url
+= '/format/json'
110 def _real_initialize(self
):
111 '''Performs necessary operations so that the information extractor is
112 ready for operation'''
113 self
._initialize
_api
()
117 '''Performs logout from the webservice'''
118 self
._download
_json
(self
.logout_url
, None, note
='Logout',
119 errnote
='Unable to log out', fatal
=False)
121 def _real_extract(self
, url
):
122 '''Extract the data necessary to download the video'''
123 video_id
= self
._match
_id
(url
)
125 metadata_url
= self
.search_url
+ \
126 '/video_id/{video_id}/format/json'.format(video_id
=video_id
)
128 metadata
= self
._download
_json
(metadata_url
, video_id
,
129 note
='Getting video metadata')
130 video
= metadata
['video'][0]
131 title_info
= video
.get('title', {})
132 title
= title_info
.get('title_long')
133 description
= title_info
.get('summary_long')
135 movie
= video
['video_assets']['movie'][0]
136 url
= movie
['url'].format(TOKEN
=self
.token
)
138 formats
= self
._extract
_m
3u8_formats
(url
, video_id
, 'mp4')
140 self
._sort
_formats
(formats
)
147 'description': description
,