| 
									
										
										
										
											2014-01-17 03:52:17 +01:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | import json | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-15 18:03:41 +01:00
										 |  |  | from .common import InfoExtractor | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  | from ..compat import compat_str | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  | from ..utils import ( | 
					
						
							|  |  |  |     int_or_none, | 
					
						
							|  |  |  |     try_get, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-11-05 12:00:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 03:52:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-15 18:03:41 +01:00
										 |  |  | class TEDIE(InfoExtractor): | 
					
						
							| 
									
										
										
										
											2015-04-20 21:42:42 +06:00
										 |  |  |     IE_NAME = 'ted' | 
					
						
							| 
									
										
										
										
											2014-03-20 16:33:23 +01:00
										 |  |  |     _VALID_URL = r'''(?x)
 | 
					
						
							|  |  |  |         (?P<proto>https?://) | 
					
						
							| 
									
										
										
										
											2015-01-05 13:11:13 +01:00
										 |  |  |         (?P<type>www|embed(?:-ssl)?)(?P<urlmain>\.ted\.com/ | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         ( | 
					
						
							|  |  |  |             (?P<type_playlist>playlists(?:/\d+)?) # We have a playlist | 
					
						
							|  |  |  |             | | 
					
						
							|  |  |  |             ((?P<type_talk>talks)) # We have a simple talk | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |             | | 
					
						
							|  |  |  |             (?P<type_watch>watch)/[^/]+/[^/]+ | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         (/lang/(.*?))? # The url may contain the language | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |         /(?P<name>[\w-]+) # Here goes the name and then ".html" | 
					
						
							| 
									
										
										
										
											2014-03-20 16:33:23 +01:00
										 |  |  |         .*)$ | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         '''
 | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |     _TESTS = [{ | 
					
						
							| 
									
										
										
										
											2014-01-17 03:52:17 +01:00
										 |  |  |         'url': 'http://www.ted.com/talks/dan_dennett_on_our_consciousness.html', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |         'md5': '0de43ac406aa3e4ea74b66c9c7789b13', | 
					
						
							| 
									
										
										
										
											2014-01-17 03:52:17 +01:00
										 |  |  |         'info_dict': { | 
					
						
							| 
									
										
										
										
											2014-03-05 14:27:45 +01:00
										 |  |  |             'id': '102', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  |             'title': 'The illusion of consciousness', | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |             'description': ('Philosopher Dan Dennett makes a compelling ' | 
					
						
							| 
									
										
										
										
											2014-11-23 21:39:15 +01:00
										 |  |  |                             'argument that not only don\'t we understand our own ' | 
					
						
							|  |  |  |                             'consciousness, but that half the time our brains are ' | 
					
						
							|  |  |  |                             'actively fooling us.'), | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  |             'uploader': 'Dan Dennett', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |             'width': 853, | 
					
						
							| 
									
										
										
										
											2014-11-12 09:30:57 +01:00
										 |  |  |             'duration': 1308, | 
					
						
							| 
									
										
										
										
											2013-06-27 20:46:46 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://www.ted.com/watch/ted-institute/ted-bcg/vishal-sikka-the-beauty-and-power-of-algorithms', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |         'md5': 'b899ac15e345fb39534d913f7606082b', | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |         'info_dict': { | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |             'id': 'tSVI8ta_P4w', | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'Vishal Sikka: The beauty and power of algorithms', | 
					
						
							| 
									
										
										
										
											2017-01-02 20:08:07 +08:00
										 |  |  |             'thumbnail': r're:^https?://.+\.jpg', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |             'description': 'md5:6261fdfe3e02f4f579cbbfc00aff73f4', | 
					
						
							|  |  |  |             'upload_date': '20140122', | 
					
						
							|  |  |  |             'uploader_id': 'TEDInstitute', | 
					
						
							|  |  |  |             'uploader': 'TED Institute', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'add_ie': ['Youtube'], | 
					
						
							| 
									
										
										
										
											2014-04-14 15:23:12 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://www.ted.com/talks/gabby_giffords_and_mark_kelly_be_passionate_be_courageous_be_your_best', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |         'md5': '71b3ab2f4233012dce09d515c9c39ce2', | 
					
						
							| 
									
										
										
										
											2014-04-14 15:23:12 +02:00
										 |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': '1972', | 
					
						
							| 
									
										
										
										
											2014-04-22 19:49:41 +07:00
										 |  |  |             'ext': 'mp4', | 
					
						
							| 
									
										
										
										
											2014-04-14 15:23:12 +02:00
										 |  |  |             'title': 'Be passionate. Be courageous. Be your best.', | 
					
						
							|  |  |  |             'uploader': 'Gabby Giffords and Mark Kelly', | 
					
						
							| 
									
										
										
										
											2014-04-22 19:49:41 +07:00
										 |  |  |             'description': 'md5:5174aed4d0f16021b704120360f72b92', | 
					
						
							| 
									
										
										
										
											2014-11-12 09:30:57 +01:00
										 |  |  |             'duration': 1128, | 
					
						
							| 
									
										
										
										
											2014-04-14 15:23:12 +02:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2014-08-28 00:58:24 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         'url': 'http://www.ted.com/playlists/who_are_the_hackers', | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': '10', | 
					
						
							|  |  |  |             'title': 'Who are the hackers?', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'playlist_mincount': 6, | 
					
						
							| 
									
										
										
										
											2014-10-15 12:24:11 +02:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         # contains a youtube video | 
					
						
							|  |  |  |         'url': 'https://www.ted.com/talks/douglas_adams_parrots_the_universe_and_everything', | 
					
						
							|  |  |  |         'add_ie': ['Youtube'], | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': '_ZG8HBuDjgc', | 
					
						
							| 
									
										
										
										
											2016-03-05 21:52:24 +01:00
										 |  |  |             'ext': 'webm', | 
					
						
							| 
									
										
										
										
											2014-10-15 12:24:11 +02:00
										 |  |  |             'title': 'Douglas Adams: Parrots the Universe and Everything', | 
					
						
							|  |  |  |             'description': 'md5:01ad1e199c49ac640cb1196c0e9016af', | 
					
						
							|  |  |  |             'uploader': 'University of California Television (UCTV)', | 
					
						
							|  |  |  |             'uploader_id': 'UCtelevision', | 
					
						
							|  |  |  |             'upload_date': '20080522', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'params': { | 
					
						
							|  |  |  |             'skip_download': True, | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2015-02-21 00:14:38 +06:00
										 |  |  |     }, { | 
					
						
							|  |  |  |         # YouTube video | 
					
						
							|  |  |  |         'url': 'http://www.ted.com/talks/jeffrey_kluger_the_sibling_bond', | 
					
						
							|  |  |  |         'add_ie': ['Youtube'], | 
					
						
							|  |  |  |         'info_dict': { | 
					
						
							|  |  |  |             'id': 'aFBIPO-P7LM', | 
					
						
							|  |  |  |             'ext': 'mp4', | 
					
						
							|  |  |  |             'title': 'The hidden power of siblings: Jeff Kluger at TEDxAsheville', | 
					
						
							|  |  |  |             'description': 'md5:3d7a4f50d95ca5dd67104e2a20f43fe1', | 
					
						
							|  |  |  |             'uploader': 'TEDx Talks', | 
					
						
							|  |  |  |             'uploader_id': 'TEDxTalks', | 
					
						
							|  |  |  |             'upload_date': '20111216', | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         'params': { | 
					
						
							|  |  |  |             'skip_download': True, | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |     }] | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-07 13:07:07 +02:00
										 |  |  |     _NATIVE_FORMATS = { | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |         'low': {'width': 320, 'height': 180}, | 
					
						
							|  |  |  |         'medium': {'width': 512, 'height': 288}, | 
					
						
							|  |  |  |         'high': {'width': 854, 'height': 480}, | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |     def _extract_info(self, webpage): | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         info_json = self._search_regex( | 
					
						
							|  |  |  |             r'(?s)q\(\s*"\w+.init"\s*,\s*({.+})\)\s*</script>', | 
					
						
							|  |  |  |             webpage, 'info json') | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |         return json.loads(info_json) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  |     def _real_extract(self, url): | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         m = re.match(self._VALID_URL, url, re.VERBOSE) | 
					
						
							| 
									
										
										
										
											2015-01-05 13:11:13 +01:00
										 |  |  |         if m.group('type').startswith('embed'): | 
					
						
							| 
									
										
										
										
											2014-03-20 16:33:23 +01:00
										 |  |  |             desktop_url = m.group('proto') + 'www' + m.group('urlmain') | 
					
						
							|  |  |  |             return self.url_result(desktop_url, 'TED') | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         name = m.group('name') | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  |         if m.group('type_talk'): | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |             return self._talk_info(url, name) | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |         elif m.group('type_watch'): | 
					
						
							|  |  |  |             return self._watch_info(url, name) | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |             return self._playlist_videos_info(url, name) | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |     def _playlist_videos_info(self, url, name): | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  |         '''Returns the videos of the playlist''' | 
					
						
							| 
									
										
										
										
											2013-11-15 14:33:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |         webpage = self._download_webpage(url, name, | 
					
						
							| 
									
										
										
										
											2014-11-23 21:39:15 +01:00
										 |  |  |                                          'Downloading playlist webpage') | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |         info = self._extract_info(webpage) | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         playlist_info = try_get( | 
					
						
							|  |  |  |             info, lambda x: x['__INITIAL_DATA__']['playlist'], | 
					
						
							|  |  |  |             dict) or info['playlist'] | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-15 14:33:51 +01:00
										 |  |  |         playlist_entries = [ | 
					
						
							| 
									
										
										
										
											2014-04-21 12:34:32 +02:00
										 |  |  |             self.url_result('http://www.ted.com/talks/' + talk['slug'], self.ie_key()) | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |             for talk in try_get( | 
					
						
							|  |  |  |                 info, lambda x: x['__INITIAL_DATA__']['talks'], | 
					
						
							|  |  |  |                 dict) or info['talks'] | 
					
						
							| 
									
										
										
										
											2013-11-15 14:33:51 +01:00
										 |  |  |         ] | 
					
						
							|  |  |  |         return self.playlist_result( | 
					
						
							| 
									
										
										
										
											2014-03-05 13:22:10 +01:00
										 |  |  |             playlist_entries, | 
					
						
							|  |  |  |             playlist_id=compat_str(playlist_info['id']), | 
					
						
							|  |  |  |             playlist_title=playlist_info['title']) | 
					
						
							| 
									
										
										
										
											2013-06-23 21:55:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 13:27:26 +01:00
										 |  |  |     def _talk_info(self, url, video_name): | 
					
						
							|  |  |  |         webpage = self._download_webpage(url, video_name) | 
					
						
							| 
									
										
										
										
											2013-11-02 19:48:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         info = self._extract_info(webpage) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         talk_info = try_get( | 
					
						
							|  |  |  |             info, lambda x: x['__INITIAL_DATA__']['talks'][0], | 
					
						
							|  |  |  |             dict) or info['talks'][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         title = talk_info['title'].strip() | 
					
						
							| 
									
										
										
										
											2013-11-02 19:48:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 00:14:38 +06:00
										 |  |  |         external = talk_info.get('external') | 
					
						
							|  |  |  |         if external: | 
					
						
							|  |  |  |             service = external['service'] | 
					
						
							|  |  |  |             self.to_screen('Found video from %s' % service) | 
					
						
							|  |  |  |             ext_url = None | 
					
						
							|  |  |  |             if service.lower() == 'youtube': | 
					
						
							|  |  |  |                 ext_url = external.get('code') | 
					
						
							| 
									
										
										
										
											2014-10-15 12:24:11 +02:00
										 |  |  |             return { | 
					
						
							|  |  |  |                 '_type': 'url', | 
					
						
							| 
									
										
										
										
											2015-02-21 00:14:38 +06:00
										 |  |  |                 'url': ext_url or external['uri'], | 
					
						
							| 
									
										
										
										
											2014-10-15 12:24:11 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         native_downloads = try_get( | 
					
						
							|  |  |  |             talk_info, lambda x: x['downloads']['nativeDownloads'], | 
					
						
							|  |  |  |             dict) or talk_info['nativeDownloads'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  |         formats = [{ | 
					
						
							|  |  |  |             'url': format_url, | 
					
						
							|  |  |  |             'format_id': format_id, | 
					
						
							|  |  |  |             'format': format_id, | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         } for (format_id, format_url) in native_downloads.items() if format_url is not None] | 
					
						
							| 
									
										
										
										
											2014-04-14 15:23:12 +02:00
										 |  |  |         if formats: | 
					
						
							|  |  |  |             for f in formats: | 
					
						
							|  |  |  |                 finfo = self._NATIVE_FORMATS.get(f['format_id']) | 
					
						
							|  |  |  |                 if finfo: | 
					
						
							|  |  |  |                     f.update(finfo) | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         player_talk = talk_info['player_talks'][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         resources_ = player_talk.get('resources') or talk_info.get('resources') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |         http_url = None | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |         for format_id, resources in resources_.items(): | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  |             if format_id == 'h264': | 
					
						
							|  |  |  |                 for resource in resources: | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |                     h264_url = resource.get('file') | 
					
						
							|  |  |  |                     if not h264_url: | 
					
						
							|  |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  |                     bitrate = int_or_none(resource.get('bitrate')) | 
					
						
							|  |  |  |                     formats.append({ | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |                         'url': h264_url, | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  |                         'format_id': '%s-%sk' % (format_id, bitrate), | 
					
						
							|  |  |  |                         'tbr': bitrate, | 
					
						
							|  |  |  |                     }) | 
					
						
							| 
									
										
										
										
											2017-01-02 20:08:07 +08:00
										 |  |  |                     if re.search(r'\d+k', h264_url): | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |                         http_url = h264_url | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  |             elif format_id == 'rtmp': | 
					
						
							|  |  |  |                 streamer = talk_info.get('streamer') | 
					
						
							|  |  |  |                 if not streamer: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 for resource in resources: | 
					
						
							|  |  |  |                     formats.append({ | 
					
						
							|  |  |  |                         'format_id': '%s-%s' % (format_id, resource.get('name')), | 
					
						
							|  |  |  |                         'url': streamer, | 
					
						
							|  |  |  |                         'play_path': resource['file'], | 
					
						
							|  |  |  |                         'ext': 'flv', | 
					
						
							|  |  |  |                         'width': int_or_none(resource.get('width')), | 
					
						
							|  |  |  |                         'height': int_or_none(resource.get('height')), | 
					
						
							|  |  |  |                         'tbr': int_or_none(resource.get('bitrate')), | 
					
						
							|  |  |  |                     }) | 
					
						
							|  |  |  |             elif format_id == 'hls': | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |                 formats.extend(self._extract_m3u8_formats( | 
					
						
							|  |  |  |                     resources.get('stream'), video_name, 'mp4', m3u8_id=format_id, fatal=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m3u8_formats = list(filter( | 
					
						
							| 
									
										
										
										
											2017-04-25 22:07:10 +07:00
										 |  |  |             lambda f: f.get('protocol') == 'm3u8' and f.get('vcodec') != 'none', | 
					
						
							| 
									
										
										
										
											2016-04-30 15:41:22 +01:00
										 |  |  |             formats)) | 
					
						
							|  |  |  |         if http_url: | 
					
						
							|  |  |  |             for m3u8_format in m3u8_formats: | 
					
						
							|  |  |  |                 bitrate = self._search_regex(r'(\d+k)', m3u8_format['url'], 'bitrate', default=None) | 
					
						
							|  |  |  |                 if not bitrate: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 f = m3u8_format.copy() | 
					
						
							|  |  |  |                 f.update({ | 
					
						
							|  |  |  |                     'url': re.sub(r'\d+k', bitrate, http_url), | 
					
						
							|  |  |  |                     'format_id': m3u8_format['format_id'].replace('hls', 'http'), | 
					
						
							|  |  |  |                     'protocol': 'http', | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |                 formats.append(f) | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         audio_download = talk_info.get('audioDownload') | 
					
						
							|  |  |  |         if audio_download: | 
					
						
							|  |  |  |             formats.append({ | 
					
						
							|  |  |  |                 'url': audio_download, | 
					
						
							|  |  |  |                 'format_id': 'audio', | 
					
						
							| 
									
										
										
										
											2015-04-20 21:42:20 +06:00
										 |  |  |                 'vcodec': 'none', | 
					
						
							| 
									
										
										
										
											2015-04-10 23:36:28 +06:00
										 |  |  |             }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |         self._sort_formats(formats) | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 14:27:45 +01:00
										 |  |  |         video_id = compat_str(talk_info['id']) | 
					
						
							| 
									
										
										
										
											2013-11-02 19:48:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-15 14:06:38 +01:00
										 |  |  |         return { | 
					
						
							| 
									
										
										
										
											2013-11-02 19:48:39 +01:00
										 |  |  |             'id': video_id, | 
					
						
							| 
									
										
										
										
											2017-07-01 18:39:01 +07:00
										 |  |  |             'title': title, | 
					
						
							|  |  |  |             'uploader': player_talk.get('speaker') or talk_info.get('speaker'), | 
					
						
							|  |  |  |             'thumbnail': player_talk.get('thumb') or talk_info.get('thumb'), | 
					
						
							| 
									
										
										
										
											2014-03-04 21:47:01 +01:00
										 |  |  |             'description': self._og_search_description(webpage), | 
					
						
							| 
									
										
										
										
											2015-02-21 22:33:11 +01:00
										 |  |  |             'subtitles': self._get_subtitles(video_id, talk_info), | 
					
						
							| 
									
										
										
										
											2013-10-04 10:32:34 +02:00
										 |  |  |             'formats': formats, | 
					
						
							| 
									
										
										
										
											2014-11-12 09:30:57 +01:00
										 |  |  |             'duration': talk_info.get('duration'), | 
					
						
							| 
									
										
										
										
											2013-10-04 10:32:34 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-15 18:03:41 +01:00
										 |  |  |     def _get_subtitles(self, video_id, talk_info): | 
					
						
							| 
									
										
										
										
											2017-07-11 21:36:45 +07:00
										 |  |  |         sub_lang_list = {} | 
					
						
							|  |  |  |         for language in try_get( | 
					
						
							|  |  |  |                 talk_info, | 
					
						
							|  |  |  |                 (lambda x: x['downloads']['languages'], | 
					
						
							|  |  |  |                  lambda x: x['languages']), list): | 
					
						
							|  |  |  |             lang_code = language.get('languageCode') or language.get('ianaCode') | 
					
						
							|  |  |  |             if not lang_code: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             sub_lang_list[lang_code] = [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     'url': 'http://www.ted.com/talks/subtitles/id/%s/lang/%s/format/%s' % (video_id, lang_code, ext), | 
					
						
							|  |  |  |                     'ext': ext, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 for ext in ['ted', 'srt'] | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         return sub_lang_list | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _watch_info(self, url, name): | 
					
						
							|  |  |  |         webpage = self._download_webpage(url, name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         config_json = self._html_search_regex( | 
					
						
							| 
									
										
										
										
											2014-12-03 21:17:11 +06:00
										 |  |  |             r'"pages\.jwplayer"\s*,\s*({.+?})\s*\)\s*</script>', | 
					
						
							| 
									
										
										
										
											2016-04-30 16:34:57 +01:00
										 |  |  |             webpage, 'config', default=None) | 
					
						
							|  |  |  |         if not config_json: | 
					
						
							|  |  |  |             embed_url = self._search_regex( | 
					
						
							|  |  |  |                 r"<iframe[^>]+class='pages-video-embed__video__object'[^>]+src='([^']+)'", webpage, 'embed url') | 
					
						
							|  |  |  |             return self.url_result(self._proto_relative_url(embed_url)) | 
					
						
							| 
									
										
										
										
											2014-12-03 21:17:11 +06:00
										 |  |  |         config = json.loads(config_json)['config'] | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |         video_url = config['video']['url'] | 
					
						
							|  |  |  |         thumbnail = config.get('image', {}).get('url') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         title = self._html_search_regex( | 
					
						
							|  |  |  |             r"(?s)<h1(?:\s+class='[^']+')?>(.+?)</h1>", webpage, 'title') | 
					
						
							|  |  |  |         description = self._html_search_regex( | 
					
						
							| 
									
										
										
										
											2014-04-21 12:37:16 +02:00
										 |  |  |             [ | 
					
						
							|  |  |  |                 r'(?s)<h4 class="[^"]+" id="h3--about-this-talk">.*?</h4>(.*?)</div>', | 
					
						
							|  |  |  |                 r'(?s)<p><strong>About this talk:</strong>\s+(.*?)</p>', | 
					
						
							|  |  |  |             ], | 
					
						
							| 
									
										
										
										
											2014-03-27 02:22:40 +01:00
										 |  |  |             webpage, 'description', fatal=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             'id': name, | 
					
						
							|  |  |  |             'url': video_url, | 
					
						
							|  |  |  |             'title': title, | 
					
						
							|  |  |  |             'thumbnail': thumbnail, | 
					
						
							|  |  |  |             'description': description, | 
					
						
							|  |  |  |         } |