diff --git a/deemix/downloader.py b/deemix/downloader.py index 197ab17..17ac5f0 100644 --- a/deemix/downloader.py +++ b/deemix/downloader.py @@ -40,6 +40,17 @@ extensions = { TrackFormats.MP4_RA1: '.mp4' } +formatsName = { + TrackFormats.FLAC: 'FLAC', + TrackFormats.LOCAL: 'MP3_MISC', + TrackFormats.MP3_320: 'MP3_320', + TrackFormats.MP3_128: 'MP3_128', + TrackFormats.DEFAULT: 'MP3_MISC', + TrackFormats.MP4_RA3: 'MP4_RA3', + TrackFormats.MP4_RA2: 'MP4_RA2', + TrackFormats.MP4_RA1: 'MP4_RA1' +} + TEMPDIR = Path(gettempdir()) / 'deemix-imgs' if not TEMPDIR.is_dir(): makedirs(TEMPDIR) @@ -98,8 +109,10 @@ def getPreferredBitrate(track, bitrate, shouldFallback, uuid=None, listener=None formats = formats_non_360 def testBitrate(track, formatNumber, formatName): + if formatName not in track.urls: + track.urls[formatName] = generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, formatNumber) request = requests.head( - generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, formatNumber), + track.urls[formatName], headers={'User-Agent': USER_AGENT_HEADER}, timeout=30 ) @@ -342,7 +355,9 @@ class Downloader: writepath = Path(currentFilename) if not trackAlreadyDownloaded or self.settings['overwriteFile'] == OverwriteOption.OVERWRITE: - track.downloadUrl = generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, track.bitrate) + if formatsName[track.bitrate] not in track.urls: + track.urls[formatsName[track.bitrate]] = generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, track.bitrate) + track.downloadUrl = track.urls[formatsName[track.bitrate]] try: with open(writepath, 'wb') as stream: @@ -415,6 +430,7 @@ class Downloader: newTrack = self.dz.gw.get_track_with_fallback(track.fallbackID) track.parseEssentialData(newTrack) track.retriveFilesizes(self.dz) + track.retriveTrackURLs(self.dz) return self.downloadWrapper(extraData, track) if not track.searched and self.settings['fallbackSearch']: self.warn(itemData, error.errid, 'search') @@ -423,6 +439,7 @@ class Downloader: newTrack = self.dz.gw.get_track_with_fallback(searchedId) track.parseEssentialData(newTrack) track.retriveFilesizes(self.dz) + track.retriveTrackURLs(self.dz) track.searched = True if self.listener: self.listener.send('queueUpdate', { 'uuid': self.downloadObject.uuid, diff --git a/deemix/types/Track.py b/deemix/types/Track.py index fa8009d..81ea8e2 100644 --- a/deemix/types/Track.py +++ b/deemix/types/Track.py @@ -23,6 +23,7 @@ class Track: self.title = name self.MD5 = "" self.mediaVersion = "" + self.trackToken = "" self.duration = 0 self.fallbackID = "0" self.filesizes = {} @@ -50,16 +51,18 @@ class Track: self.artistsString = "" self.mainArtistsString = "" self.featArtistsString = "" + self.urls = {} def parseEssentialData(self, trackAPI_gw, trackAPI=None): self.id = str(trackAPI_gw['SNG_ID']) self.duration = trackAPI_gw['DURATION'] + self.trackToken = trackAPI_gw['TRACK_TOKEN'] self.MD5 = trackAPI_gw.get('MD5_ORIGIN') if not self.MD5: if trackAPI and trackAPI.get('md5_origin'): self.MD5 = trackAPI['md5_origin'] - else: - raise MD5NotFound + #else: + # raise MD5NotFound self.mediaVersion = trackAPI_gw['MEDIA_VERSION'] self.fallbackID = "0" if 'FALLBACK' in trackAPI_gw: @@ -104,6 +107,7 @@ class Track: except APIError: trackAPI = None self.parseEssentialData(trackAPI_gw, trackAPI) + self.retriveTrackURLs(dz) if self.local: self.parseLocalTrackData(trackAPI_gw) @@ -241,6 +245,12 @@ class Track: self.artist[artist['role']] = [] self.artist[artist['role']].append(artist['name']) + def retriveTrackURLs(self, dz): + urls = dz.get_tracks_urls(self.trackToken) + self.urls = {} + for url in urls[0]['media']: + self.urls[url['format']] = url['sources'][0]['url'] + def removeDuplicateArtists(self): (self.artist, self.artists) = removeDuplicateArtists(self.artist, self.artists)