]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/adobetv.py
1 from __future__
import unicode_literals
5 from .common
import InfoExtractor
6 from ..compat
import compat_str
18 class AdobeTVBaseIE(InfoExtractor
):
19 _API_BASE_URL
= 'http://tv.adobe.com/api/v4/'
22 class AdobeTVIE(AdobeTVBaseIE
):
23 _VALID_URL
= r
'https?://tv\.adobe\.com/(?:(?P<language>fr|de|es|jp)/)?watch/(?P<show_urlname>[^/]+)/(?P<id>[^/]+)'
26 'url': 'http://tv.adobe.com/watch/the-complete-picture-with-julieanne-kost/quick-tip-how-to-draw-a-circle-around-an-object-in-photoshop/',
27 'md5': '9bc5727bcdd55251f35ad311ca74fa1e',
31 'title': 'Quick Tip - How to Draw a Circle Around an Object in Photoshop',
32 'description': 'md5:99ec318dc909d7ba2a1f2b038f7d2311',
33 'thumbnail': r
're:https?://.*\.jpg$',
34 'upload_date': '20110914',
40 def _real_extract(self
, url
):
41 language
, show_urlname
, urlname
= re
.match(self
._VALID
_URL
, url
).groups()
45 video_data
= self
._download
_json
(
46 self
._API
_BASE
_URL
+ 'episode/get/?language=%s&show_urlname=%s&urlname=%s&disclosure=standard' % (language
, show_urlname
, urlname
),
51 'format_id': source
.get('quality_level') or source
['url'].split('-')[-1].split('.')[0] or None,
52 'width': int_or_none(source
.get('width')),
53 'height': int_or_none(source
.get('height')),
54 'tbr': int_or_none(source
.get('video_data_rate')),
55 } for source
in video_data
['videos']]
56 self
._sort
_formats
(formats
)
59 'id': compat_str(video_data
['id']),
60 'title': video_data
['title'],
61 'description': video_data
.get('description'),
62 'thumbnail': video_data
.get('thumbnail'),
63 'upload_date': unified_strdate(video_data
.get('start_date')),
64 'duration': parse_duration(video_data
.get('duration')),
65 'view_count': str_to_int(video_data
.get('playcount')),
70 class AdobeTVPlaylistBaseIE(AdobeTVBaseIE
):
71 def _parse_page_data(self
, page_data
):
72 return [self
.url_result(self
._get
_element
_url
(element_data
)) for element_data
in page_data
]
74 def _extract_playlist_entries(self
, url
, display_id
):
75 page
= self
._download
_json
(url
, display_id
)
76 entries
= self
._parse
_page
_data
(page
['data'])
77 for page_num
in range(2, page
['paging']['pages'] + 1):
78 entries
.extend(self
._parse
_page
_data
(
79 self
._download
_json
(url
+ '&page=%d' % page_num
, display_id
)['data']))
83 class AdobeTVShowIE(AdobeTVPlaylistBaseIE
):
84 _VALID_URL
= r
'https?://tv\.adobe\.com/(?:(?P<language>fr|de|es|jp)/)?show/(?P<id>[^/]+)'
87 'url': 'http://tv.adobe.com/show/the-complete-picture-with-julieanne-kost',
90 'title': 'The Complete Picture with Julieanne Kost',
91 'description': 'md5:fa50867102dcd1aa0ddf2ab039311b27',
93 'playlist_mincount': 136,
96 def _get_element_url(self
, element_data
):
97 return element_data
['urls'][0]
99 def _real_extract(self
, url
):
100 language
, show_urlname
= re
.match(self
._VALID
_URL
, url
).groups()
103 query
= 'language=%s&show_urlname=%s' % (language
, show_urlname
)
105 show_data
= self
._download
_json
(self
._API
_BASE
_URL
+ 'show/get/?%s' % query
, show_urlname
)['data'][0]
107 return self
.playlist_result(
108 self
._extract
_playlist
_entries
(self
._API
_BASE
_URL
+ 'episode/?%s' % query
, show_urlname
),
109 compat_str(show_data
['id']),
110 show_data
['show_name'],
111 show_data
['show_description'])
114 class AdobeTVChannelIE(AdobeTVPlaylistBaseIE
):
115 _VALID_URL
= r
'https?://tv\.adobe\.com/(?:(?P<language>fr|de|es|jp)/)?channel/(?P<id>[^/]+)(?:/(?P<category_urlname>[^/]+))?'
118 'url': 'http://tv.adobe.com/channel/development',
122 'playlist_mincount': 96,
125 def _get_element_url(self
, element_data
):
126 return element_data
['url']
128 def _real_extract(self
, url
):
129 language
, channel_urlname
, category_urlname
= re
.match(self
._VALID
_URL
, url
).groups()
132 query
= 'language=%s&channel_urlname=%s' % (language
, channel_urlname
)
134 query
+= '&category_urlname=%s' % category_urlname
136 return self
.playlist_result(
137 self
._extract
_playlist
_entries
(self
._API
_BASE
_URL
+ 'show/?%s' % query
, channel_urlname
),
141 class AdobeTVVideoIE(InfoExtractor
):
142 _VALID_URL
= r
'https?://video\.tv\.adobe\.com/v/(?P<id>\d+)'
145 # From https://helpx.adobe.com/acrobat/how-to/new-experience-acrobat-dc.html?set=acrobat--get-started--essential-beginners
146 'url': 'https://video.tv.adobe.com/v/2456/',
147 'md5': '43662b577c018ad707a63766462b1e87',
151 'title': 'New experience with Acrobat DC',
152 'description': 'New experience with Acrobat DC',
157 def _real_extract(self
, url
):
158 video_id
= self
._match
_id
(url
)
159 webpage
= self
._download
_webpage
(url
, video_id
)
161 video_data
= self
._parse
_json
(self
._search
_regex
(
162 r
'var\s+bridge\s*=\s*([^;]+);', webpage
, 'bridged data'), video_id
)
165 'format_id': '%s-%s' % (determine_ext(source
['src']), source
.get('height')),
166 'url': source
['src'],
167 'width': int_or_none(source
.get('width')),
168 'height': int_or_none(source
.get('height')),
169 'tbr': int_or_none(source
.get('bitrate')),
170 } for source
in video_data
['sources']]
171 self
._sort
_formats
(formats
)
173 # For both metadata and downloaded files the duration varies among
174 # formats. I just pick the max one
175 duration
= max(filter(None, [
176 float_or_none(source
.get('duration'), scale
=1000)
177 for source
in video_data
['sources']]))
180 for translation
in video_data
.get('translations', []):
181 lang_id
= translation
.get('language_w3c') or ISO639Utils
.long2short(translation
['language_medium'])
182 if lang_id
not in subtitles
:
183 subtitles
[lang_id
] = []
184 subtitles
[lang_id
].append({
185 'url': translation
['vttPath'],
192 'title': video_data
['title'],
193 'description': video_data
.get('description'),
194 'thumbnail': video_data
['video'].get('poster'),
195 'duration': duration
,
196 'subtitles': subtitles
,