beatport.py (3419B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 import re 5 6 from .common import InfoExtractor 7 from ..compat import compat_str 8 from ..utils import int_or_none 9 10 11 class BeatportIE(InfoExtractor): 12 _VALID_URL = r'https?://(?:www\.|pro\.)?beatport\.com/track/(?P<display_id>[^/]+)/(?P<id>[0-9]+)' 13 _TESTS = [{ 14 'url': 'https://beatport.com/track/synesthesia-original-mix/5379371', 15 'md5': 'b3c34d8639a2f6a7f734382358478887', 16 'info_dict': { 17 'id': '5379371', 18 'display_id': 'synesthesia-original-mix', 19 'ext': 'mp4', 20 'title': 'Froxic - Synesthesia (Original Mix)', 21 }, 22 }, { 23 'url': 'https://beatport.com/track/love-and-war-original-mix/3756896', 24 'md5': 'e44c3025dfa38c6577fbaeb43da43514', 25 'info_dict': { 26 'id': '3756896', 27 'display_id': 'love-and-war-original-mix', 28 'ext': 'mp3', 29 'title': 'Wolfgang Gartner - Love & War (Original Mix)', 30 }, 31 }, { 32 'url': 'https://beatport.com/track/birds-original-mix/4991738', 33 'md5': 'a1fd8e8046de3950fd039304c186c05f', 34 'info_dict': { 35 'id': '4991738', 36 'display_id': 'birds-original-mix', 37 'ext': 'mp4', 38 'title': "Tos, Middle Milk, Mumblin' Johnsson - Birds (Original Mix)", 39 } 40 }] 41 42 def _real_extract(self, url): 43 mobj = re.match(self._VALID_URL, url) 44 track_id = mobj.group('id') 45 display_id = mobj.group('display_id') 46 47 webpage = self._download_webpage(url, display_id) 48 49 playables = self._parse_json( 50 self._search_regex( 51 r'window\.Playables\s*=\s*({.+?});', webpage, 52 'playables info', flags=re.DOTALL), 53 track_id) 54 55 track = next(t for t in playables['tracks'] if t['id'] == int(track_id)) 56 57 title = ', '.join((a['name'] for a in track['artists'])) + ' - ' + track['name'] 58 if track['mix']: 59 title += ' (' + track['mix'] + ')' 60 61 formats = [] 62 for ext, info in track['preview'].items(): 63 if not info['url']: 64 continue 65 fmt = { 66 'url': info['url'], 67 'ext': ext, 68 'format_id': ext, 69 'vcodec': 'none', 70 } 71 if ext == 'mp3': 72 fmt['preference'] = 0 73 fmt['acodec'] = 'mp3' 74 fmt['abr'] = 96 75 fmt['asr'] = 44100 76 elif ext == 'mp4': 77 fmt['preference'] = 1 78 fmt['acodec'] = 'aac' 79 fmt['abr'] = 96 80 fmt['asr'] = 44100 81 formats.append(fmt) 82 self._sort_formats(formats) 83 84 images = [] 85 for name, info in track['images'].items(): 86 image_url = info.get('url') 87 if name == 'dynamic' or not image_url: 88 continue 89 image = { 90 'id': name, 91 'url': image_url, 92 'height': int_or_none(info.get('height')), 93 'width': int_or_none(info.get('width')), 94 } 95 images.append(image) 96 97 return { 98 'id': compat_str(track.get('id')) or track_id, 99 'display_id': track.get('slug') or display_id, 100 'title': title, 101 'formats': formats, 102 'thumbnails': images, 103 }