]>
jfr.im git - yt-dlp.git/blob - youtube_dl/extractor/noco.py
2 from __future__
import unicode_literals
8 from .common
import InfoExtractor
12 compat_urllib_request
,
21 class NocoIE(InfoExtractor
):
22 _VALID_URL
= r
'http://(?:(?:www\.)?noco\.tv/emission/|player\.noco\.tv/\?idvideo=)(?P<id>\d+)'
23 _LOGIN_URL
= 'http://noco.tv/do.php'
24 _API_URL_TEMPLATE
= 'https://api.noco.tv/1.1/%s?ts=%s&tk=%s'
25 _SUB_LANG_TEMPLATE
= '&sub_lang=%s'
26 _NETRC_MACHINE
= 'noco'
30 'url': 'http://noco.tv/emission/11538/nolife/ami-ami-idol-hello-france/',
31 'md5': '0a993f0058ddbcd902630b2047ef710e',
35 'title': 'Ami Ami Idol - Hello! France',
36 'description': 'md5:4eaab46ab68fa4197a317a88a53d3b86',
37 'upload_date': '20140412',
42 'skip': 'Requires noco account',
45 'url': 'http://noco.tv/emission/12610/lbl42/the-guild/s01e01-wake-up-call',
46 'md5': 'c190f1f48e313c55838f1f412225934d',
50 'title': 'The Guild #1 - Wake-Up Call',
52 'upload_date': '20140627',
57 'skip': 'Requires noco account',
61 def _real_initialize(self
):
65 (username
, password
) = self
._get
_login
_info
()
75 request
= compat_urllib_request
.Request(self
._LOGIN
_URL
, compat_urllib_parse
.urlencode(login_form
))
76 request
.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
78 login
= self
._download
_json
(request
, None, 'Logging in as %s' % username
)
81 raise ExtractorError('Unable to login: %s' % clean_html(login
['erreur']), expected
=True)
83 def _call_api(self
, path
, video_id
, note
, sub_lang
=None):
84 ts
= compat_str(int(time
.time() * 1000))
85 tk
= hashlib
.md5((hashlib
.md5(ts
.encode('ascii')).hexdigest() + '#8S?uCraTedap6a').encode('ascii')).hexdigest()
86 url
= self
._API
_URL
_TEMPLATE
% (path
, ts
, tk
)
88 url
+= self
._SUB
_LANG
_TEMPLATE
% sub_lang
90 resp
= self
._download
_json
(url
, video_id
, note
)
92 if isinstance(resp
, dict) and resp
.get('error'):
93 self
._raise
_error
(resp
['error'], resp
['description'])
97 def _raise_error(self
, error
, description
):
99 '%s returned error: %s - %s' % (self
.IE_NAME
, error
, description
),
102 def _real_extract(self
, url
):
103 mobj
= re
.match(self
._VALID
_URL
, url
)
104 video_id
= mobj
.group('id')
106 options
= self
._call
_api
('users/init', None, 'Downloading user options JSON')['options']
107 audio_lang
= options
.get('audio_language', 'fr')
109 medias
= self
._call
_api
(
110 'shows/%s/medias' % video_id
,
111 video_id
, 'Downloading video JSON')
113 show
= self
._call
_api
(
114 'shows/by_id/%s' % video_id
,
115 video_id
, 'Downloading show JSON')[0]
117 if audio_lang
== 'original':
118 audio_lang
= show
['original_lang']
120 audio_lang
= list(medias
.keys())[0]
121 elif not audio_lang
in medias
:
124 qualities
= self
._call
_api
(
126 video_id
, 'Downloading qualities JSON')
130 for lang
, lang_dict
in medias
[audio_lang
]['video_list'].items():
131 for format_id
, fmt
in lang_dict
['quality_list'].items():
132 format_id_extended
= '%s-%s' % (lang
, format_id
) if lang
!= 'none' else format_id
134 video
= self
._call
_api
(
135 'shows/%s/video/%s/%s' % (video_id
, format_id
.lower(), audio_lang
),
136 video_id
, 'Downloading %s video JSON' % format_id_extended
,
137 lang
if lang
!= 'none' else None)
139 file_url
= video
['file']
143 if file_url
in ['forbidden', 'not found']:
144 popmessage
= video
['popmessage']
145 self
._raise
_error
(popmessage
['title'], popmessage
['message'])
149 'format_id': format_id_extended
,
150 'width': fmt
['res_width'],
151 'height': fmt
['res_lines'],
152 'abr': fmt
['audiobitrate'],
153 'vbr': fmt
['videobitrate'],
154 'filesize': fmt
['filesize'],
155 'format_note': qualities
[format_id
]['quality_name'],
156 'preference': qualities
[format_id
]['priority'],
159 self
._sort
_formats
(formats
)
161 upload_date
= unified_strdate(show
['online_date_start_utc'])
162 uploader
= show
['partner_name']
163 uploader_id
= show
['partner_key']
164 duration
= show
['duration_ms'] / 1000.0
167 for thumbnail_key
, thumbnail_url
in show
.items():
168 m
= re
.search(r
'^screenshot_(?P<width>\d+)x(?P<height>\d+)$', thumbnail_key
)
172 'url': thumbnail_url
,
173 'width': int(m
.group('width')),
174 'height': int(m
.group('height')),
177 episode
= show
.get('show_TT') or show
.get('show_OT')
178 family
= show
.get('family_TT') or show
.get('family_OT')
179 episode_number
= show
.get('episode_number')
185 title
+= ' #' + compat_str(episode_number
)
187 title
+= ' - ' + episode
189 description
= show
.get('show_resume') or show
.get('family_resume')
194 'description': description
,
195 'thumbnails': thumbnails
,
196 'upload_date': upload_date
,
197 'uploader': uploader
,
198 'uploader_id': uploader_id
,
199 'duration': duration
,