mirror of
				https://github.com/ytdl-org/youtube-dl.git
				synced 2025-10-29 09:26:20 -07:00 
			
		
		
		
	Mixcloud IE
This commit is contained in:
		
							
								
								
									
										120
									
								
								youtube-dl
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								youtube-dl
									
									
									
									
									
								
							| @@ -3608,7 +3608,126 @@ class InfoQIE(InfoExtractor): | ||||
| 		except UnavailableVideoError, err: | ||||
| 			self._downloader.trouble(u'\nERROR: unable to download ' + video_url) | ||||
|  | ||||
| class MixcloudIE(InfoExtractor): | ||||
| 	"""Information extractor for www.mixcloud.com""" | ||||
| 	_VALID_URL = r'^(?:https?://)?(?:www\.)?mixcloud\.com/([\w\d-]+)/([\w\d-]+)' | ||||
| 	IE_NAME = u'mixcloud' | ||||
|  | ||||
| 	def __init__(self, downloader=None): | ||||
| 		InfoExtractor.__init__(self, downloader) | ||||
|  | ||||
| 	def report_download_json(self, file_id): | ||||
| 		"""Report JSON download.""" | ||||
| 		self._downloader.to_screen(u'[%s] Downloading json' % self.IE_NAME) | ||||
|  | ||||
| 	def report_extraction(self, file_id): | ||||
| 		"""Report information extraction.""" | ||||
| 		self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, file_id)) | ||||
|  | ||||
| 	def get_urls(self, jsonData, fmt, bitrate='best'): | ||||
| 		"""Get urls from 'audio_formats' section in json""" | ||||
| 		file_url = None | ||||
| 		try: | ||||
| 			bitrate_list = jsonData[fmt] | ||||
| 			if bitrate is None or bitrate == 'best' or bitrate not in bitrate_list: | ||||
| 				bitrate = max(bitrate_list) # select highest | ||||
|  | ||||
| 			url_list = jsonData[fmt][bitrate] | ||||
| 		except TypeError: # we have no bitrate info. | ||||
| 			url_list = jsonData[fmt] | ||||
| 				 | ||||
| 		return url_list | ||||
| 			 | ||||
| 	def check_urls(self, url_list): | ||||
| 		"""Returns 1st active url from list""" | ||||
| 		for url in url_list: | ||||
| 			try: | ||||
| 				urllib2.urlopen(url) | ||||
| 				return url | ||||
| 			except (urllib2.URLError, httplib.HTTPException, socket.error), err: | ||||
| 				url = None | ||||
|  | ||||
| 		return None | ||||
|  | ||||
| 	def _print_formats(self, formats): | ||||
| 		print 'Available formats:' | ||||
| 		for fmt in formats.keys(): | ||||
| 			for b in formats[fmt]: | ||||
| 				try: | ||||
| 					ext = formats[fmt][b][0] | ||||
| 					print '%s\t%s\t[%s]' % (fmt, b, ext.split('.')[-1]) | ||||
| 				except TypeError: # we have no bitrate info | ||||
| 					ext = formats[fmt][0] | ||||
| 					print '%s\t%s\t[%s]' % (fmt, '??', ext.split('.')[-1]) | ||||
| 					break | ||||
|  | ||||
| 	def _real_extract(self, url): | ||||
| 		mobj = re.match(self._VALID_URL, url) | ||||
| 		if mobj is None: | ||||
| 			self._downloader.trouble(u'ERROR: invalid URL: %s' % url) | ||||
| 			return | ||||
| 		# extract uploader & filename from url | ||||
| 		uploader = mobj.group(1).decode('utf-8') | ||||
| 		file_id = uploader + "-" + mobj.group(2).decode('utf-8') | ||||
|  | ||||
| 		# construct API request | ||||
| 		file_url = 'http://www.mixcloud.com/api/1/cloudcast/' + '/'.join(url.split('/')[-3:-1]) + '.json' | ||||
| 		# retrieve .json file with links to files | ||||
| 		request = urllib2.Request(file_url) | ||||
| 		try: | ||||
| 			self.report_download_json(file_url) | ||||
| 			jsonData = urllib2.urlopen(request).read() | ||||
| 		except (urllib2.URLError, httplib.HTTPException, socket.error), err: | ||||
| 			self._downloader.trouble(u'ERROR: Unable to retrieve file: %s' % str(err)) | ||||
| 			return | ||||
|  | ||||
| 		# parse JSON | ||||
| 		json_data = json.loads(jsonData) | ||||
| 		player_url = json_data['player_swf_url'] | ||||
| 		formats = dict(json_data['audio_formats']) | ||||
|  | ||||
| 		req_format = self._downloader.params.get('format', None) | ||||
| 		bitrate = None | ||||
|  | ||||
| 		if self._downloader.params.get('listformats', None): | ||||
| 			self._print_formats(formats) | ||||
| 			return | ||||
|  | ||||
| 		if req_format is None or req_format == 'best': | ||||
| 			for format_param in formats.keys(): | ||||
| 				url_list = self.get_urls(formats, format_param) | ||||
| 				# check urls | ||||
| 				file_url = self.check_urls(url_list) | ||||
| 				if file_url is not None: | ||||
| 					break # got it! | ||||
| 		else: | ||||
| 			if req_format not in formats.keys(): | ||||
| 				self._downloader.trouble(u'ERROR: format is not available') | ||||
| 				return | ||||
|  | ||||
| 			url_list = self.get_urls(formats, req_format) | ||||
| 			file_url = self.check_urls(url_list) | ||||
| 			format_param = req_format | ||||
|  | ||||
| 		# We have audio | ||||
| 		self._downloader.increment_downloads() | ||||
| 		try: | ||||
| 			# Process file information | ||||
| 			self._downloader.process_info({ | ||||
| 				'id':		file_id.decode('utf-8'), | ||||
| 				'url':		file_url.decode('utf-8'), | ||||
| 				'uploader':	uploader.decode('utf-8'), | ||||
| 				'upload_date':	u'NA', | ||||
| 				'title':	json_data['name'], | ||||
| 				'stitle':	_simplify_title(json_data['name']), | ||||
| 				'ext':		file_url.split('.')[-1].decode('utf-8'), | ||||
| 				'format':	(format_param is None and u'NA' or format_param.decode('utf-8')), | ||||
| 				'thumbnail':    json_data['thumbnail_url'], | ||||
| 				'description':  json_data['description'], | ||||
| 				'player_url':	player_url.decode('utf-8'), | ||||
| 			}) | ||||
| 		except UnavailableVideoError, err: | ||||
| 			self._downloader.trouble(u'ERROR: unable to download file') | ||||
|  | ||||
| class PostProcessor(object): | ||||
| 	"""Post Processor class. | ||||
| @@ -4008,6 +4127,7 @@ def gen_extractors(): | ||||
| 		XVideosIE(), | ||||
| 		SoundcloudIE(), | ||||
| 		InfoQIE(), | ||||
| 		MixcloudIE(), | ||||
|  | ||||
| 		GenericIE() | ||||
| 	] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user