diff --git a/SpotifyRecorder.py b/SpotifyRecorder.py index a9d5f316e2fd4c58c8a95540c963b95a51ea33d3..9aab8d6db07b4ed57a1f119dbdad302bcae844e9 100644 --- a/SpotifyRecorder.py +++ b/SpotifyRecorder.py @@ -26,7 +26,9 @@ class SpotifyRecorder: playlist: Dict[str, str], spotifyDeviceName: str, audioDeviceName: str, - destinationFolder: str): + destinationFolder: str, + startNumber: int = 0, + limit: int = -1): self._clientID = clientID self._clientSecret = clientSecret self._redirectUrl = redirectUrl @@ -36,11 +38,11 @@ class SpotifyRecorder: self._spotifyDeviceName = spotifyDeviceName self._audioDeviceName = audioDeviceName self._destinationFolder = destinationFolder + self._startNumber = startNumber + self._limit = limit os.makedirs(self._destinationFolder, exist_ok=True) - # TODO: options specify range (start / stop track) or only offset index + limit - self._spotify = self.login() def login(self) -> spotipy.Spotify: @@ -53,16 +55,14 @@ class SpotifyRecorder: return spotipy.Spotify(client_credentials_manager=client_credentials_manager) def run(self): - LOGGER.info(f'>>> Fetching all tracks for playlist {self._playlist["name"]}...') - allTracks = [] + LOGGER.info(f'Fetching all tracks for playlist {self._playlist["name"]}...') playlist = self.__get_playlist(self._playlist['user'], self._playlist['id']) - allTracks.extend(self.__get_tracks(playlist)) - LOGGER.info(f'>>> Found {len(allTracks)} tracks') + tracks = self.__get_tracks(playlist) - self.__record_tracks(allTracks) + self.__record_tracks(tracks) def __get_playlist(self, username: str, playlistID: str) -> Dict: - LOGGER.info(f'>>> Fetching playlist with ID: {playlistID} by {username}...') + LOGGER.info(f'Fetching playlist with ID: {playlistID} by {username}...') identifier = f'spotify:user:{username}:playlist:{playlistID}' playlist = self._spotify.playlist(identifier) LOGGER.info(f'Found playlist "{playlist["name"]}"') @@ -76,7 +76,7 @@ class SpotifyRecorder: tracks = self._spotify.next(tracks) results.extend(tracks['items']) - LOGGER.info(f'Fetched {len(results)} tracks') + LOGGER.info(f'Found {len(tracks)} tracks in playlist') return results def __extract_track_uris(self, tracks: List) -> List[str]: @@ -88,18 +88,26 @@ class SpotifyRecorder: recordedTracks = [] skippedTracks = [] errorTracks = [] - for index, track in enumerate(tracks[:2]): + + if self._limit == -1: + LOGGER.info(f'Recording track #{self._startNumber} to all') + tracks = tracks[self._startNumber:] + else: + LOGGER.info(f'Recording track #{self._startNumber} to (including) #{self._startNumber + self._limit - 1}') + tracks = tracks[self._startNumber:self._startNumber + self._limit] + + for index, track in enumerate(tracks): if track['is_local']: - # TODO: # It's not possible to add a local track to a playlist using the web API. # https://github.com/plamere/spotipy/issues/793#issuecomment-1082421408 LOGGER.info(f'Skipping local track "{track["track"]["name"]}"') skippedTracks.append(track['track']['name']) continue - LOGGER.info(f'Recording track {index + 1}/{len(tracks)}: "{track["track"]["name"]}"...') + indexInPlaylist = self._startNumber + index + LOGGER.info(f'>>> Recording track {index + 1}/{len(tracks)}: #{indexInPlaylist} "{track["track"]["name"]}"...') try: - filePath = self.__determine_file_path(index + 1, track) + filePath = self.__determine_file_path(indexInPlaylist + 1, track) recorder = SpotifyAudioRecorder(self._audioDeviceName, filePath) with recorder.record(): self.__play_track(deviceId, track['track']['uri']) @@ -123,7 +131,7 @@ class SpotifyRecorder: def __wait_for_track_end(self, track, timeWaitedForPlaying: float) -> None: trackDurationInMs = track['track']['duration_ms'] trackDurationInSeconds = trackDurationInMs // 1000 - LOGGER.info(f'Track duration: {self.__convert_seconds_to_duration(trackDurationInSeconds)}') + LOGGER.info(f'\tTrack duration: {self.__convert_seconds_to_duration(trackDurationInSeconds)}') startTime = time.time() @@ -138,7 +146,7 @@ class SpotifyRecorder: if remainingTimeInMs > self._THRESHOLD_TRACK_END_IN_MS: sleepTime = remainingTimeInSeconds / 2 - LOGGER.debug(f'Waiting for track to end (remaining: ' + LOGGER.debug(f'\t\tWaiting for track to end (remaining: ' f'{self.__convert_seconds_to_duration(remainingTimeInSeconds)}, ' f'sleep: {self.__convert_seconds_to_duration(int(sleepTime))}s)...') time.sleep(sleepTime) @@ -175,13 +183,13 @@ class SpotifyRecorder: self._spotify.start_playback(device_id=deviceId, uris=[trackUri]) def __wait_for_track_playing(self) -> float: - LOGGER.debug(f'Wait for track to start playing...') + LOGGER.debug(f'\t\tWait for track to start playing...') startTime = time.time() duration = 0 while time.time() - startTime < self._MAX_WAIT_TIME_TRACK_STARTING_IN_S: if self._spotify.current_playback()['is_playing']: duration = time.time() - startTime - LOGGER.debug(f'Track started playing after {duration:.1f}s') + LOGGER.debug(f'\t\tTrack started playing after {duration:.1f}s') break time.sleep(1) @@ -201,7 +209,9 @@ if __name__ == '__main__': SETTINGS['playlist'], SETTINGS['spotifyDeviceName'], SETTINGS['audioDeviceName'], - SETTINGS['destinationFolder']) + SETTINGS['destinationFolder'], + SETTINGS['startNumber'], + SETTINGS['limit'],) spotifyBackup.run() diff --git a/config/settings-recorder-example.json b/config/settings-recorder-example.json index c0e31dfd32ce83fc86544bc84574dc9e8da030a0..8c8cbd3a84b0bd4883c78978aaba96fe08d8314c 100644 --- a/config/settings-recorder-example.json +++ b/config/settings-recorder-example.json @@ -10,6 +10,8 @@ "spotifyDeviceName": "MYDEVICE", "audioDeviceName": "3/4 - Musik (2- GIGAPort HD Audio driver) [Loopback]", "destinationFolder": "", + "startNumber": 1, + "limit": -1, "redirectUrl": "http://localhost:8080", "openBrowser": false, "cacheFilePath": ".cache"