From 007fc0be67c9bfefab0e73278c19e4bb133dece9 Mon Sep 17 00:00:00 2001 From: Ritiek Malhotra Date: Thu, 7 May 2020 23:38:34 +0530 Subject: [PATCH] Faster generation of m3u playlists --- spotdl/command_line/lib.py | 33 ++++++-------- spotdl/metadata_search.py | 91 ++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 69 deletions(-) diff --git a/spotdl/command_line/lib.py b/spotdl/command_line/lib.py index e553731..bef4004 100644 --- a/spotdl/command_line/lib.py +++ b/spotdl/command_line/lib.py @@ -121,43 +121,36 @@ class Spotdl: target_file = "{}.m3u".format(track_file.split(".")[0]) total_tracks = len(tracks) - logger.info("Generating {0} from {1} YouTube URLs".format(target_file, total_tracks)) + logger.info("Generating {0} from {1} YouTube URLs.".format(target_file, total_tracks)) with open(target_file, "w") as output_file: output_file.write("#EXTM3U\n\n") - youtube_searcher = YouTubeSearch() videos = [] for n, track in enumerate(tracks, 1): try: - search_results = youtube_searcher.search(search_query) - if not search_results: - raise NoYouTubeVideoFoundError( - 'YouTube returned no videos for the search query "{}".'.format(search_query) - ) - video = search_results.bestmatch() - if not video: - raise NoYouTubeVideoMatchError( - 'No matching videos found on YouTube for the search query "{}".'.format(search_query) - ) + search_metadata = MetadataSearch( + track, + lyrics=False, + yt_search_format=self.arguments["search_format"], + yt_manual=self.arguments["manual"] + ) + video = search_metadata.best_on_youtube_search() except (NoYouTubeVideoFoundError, NoYouTubeVideoMatchError) as e: logger.error(e.args[0]) else: - print(video) - exit() logger.info( "Matched track {0}/{1} ({2})".format( str(n).zfill(len(str(total_tracks))), total_tracks, - content.watchv_url + video["url"], ) ) - logger.debug(track) m3u_key = "#EXTINF:{duration},{title}\n{youtube_url}\n".format( - duration=internals.get_sec(content.duration), - title=content.title, - youtube_url=content.watchv_url, + duration=spotdl.util.get_sec(video["duration"]), + title=video["title"], + youtube_url=video["url"], ) - logger.debug(m3u_key) + logger.debug(m3u_key.strip()) with open(target_file, "a") as output_file: output_file.write(m3u_key) diff --git a/spotdl/metadata_search.py b/spotdl/metadata_search.py index 54c74c3..a5d17ec 100644 --- a/spotdl/metadata_search.py +++ b/spotdl/metadata_search.py @@ -138,6 +138,45 @@ class MetadataSearch: return metadata + def best_on_youtube_search(self): + track_type_mapper = { + "spotify": self._best_on_youtube_search_for_type_spotify, + "youtube": self._best_on_youtube_search_for_type_youtube, + "query": self._best_on_youtube_search_for_type_query, + } + caller = track_type_mapper[self.track_type] + video = caller(self.track) + return video + + def _best_on_youtube_search_for_type_query(self, query): + videos = self.providers["youtube"].search(query) + if not videos: + raise NoYouTubeVideoFoundError( + 'YouTube returned no videos for the search query "{}".'.format(query) + ) + if self.yt_manual: + video = prompt_for_youtube_search_result(videos) + else: + video = videos.bestmatch() + + if video is None: + raise NoYouTubeVideoMatchError( + 'No matching videos found on YouTube for the search query "{}".'.format( + search_query + ) + ) + return video + + def _best_on_youtube_search_for_type_youtube(self, url): + video = self._best_on_youtube_search_for_type_query(url) + return video + + def _best_on_youtube_search_for_type_spotify(self, url): + spotify_metadata = self._on_spotify_for_type_spotify(self.track) + search_query = spotdl.metadata.format_string(self.yt_search_format, spotify_metadata) + video = self._best_on_youtube_search_for_type_query(search_query) + return video + def _on_youtube_and_spotify_for_type_spotify(self): logger.debug("Extracting YouTube and Spotify metadata for input Spotify URI.") spotify_metadata = self._on_spotify_for_type_spotify(self.track) @@ -146,23 +185,7 @@ class MetadataSearch: spotify_metadata, ) search_query = spotdl.metadata.format_string(self.yt_search_format, spotify_metadata) - videos = self.providers["youtube"].search(search_query) - if not videos: - raise NoYouTubeVideoFoundError( - 'YouTube returned no videos for the search query "{}".'.format(search_query) - ) - if self.yt_manual: - youtube_video = prompt_for_youtube_search_result(videos) - else: - youtube_video = videos.bestmatch() - - if youtube_video is None: - raise NoYouTubeVideoMatchError( - 'No matching videos found on YouTube for the search query "{}".'.format( - search_query - ) - ) - + youtube_video = self._best_on_youtube_search_for_type_spotify(search_query) youtube_metadata = self.providers["youtube"].from_url(youtube_video["url"]) metadata = spotdl.util.merge( youtube_metadata, @@ -207,23 +230,7 @@ class MetadataSearch: spotify_metadata, ) search_query = spotdl.metadata.format_string(self.yt_search_format, spotify_metadata) - videos = self.providers["youtube"].search(search_query) - if not videos: - raise NoYouTubeVideoFoundError( - 'YouTube returned no videos for the search query "{}".'.format(search_query) - ) - if self.yt_manual: - youtube_video = prompt_for_youtube_search_result(videos) - else: - youtube_video = videos.bestmatch() - - if youtube_video is None: - raise NoYouTubeVideoMatchError( - 'No matching videos found on YouTube for the search query "{}".'.format( - search_query - ) - ) - + youtube_video = self._best_on_youtube_search_for_type_spotify(search_query) youtube_metadata = self.providers["youtube"].from_url(youtube_video["url"]) return youtube_metadata @@ -234,21 +241,7 @@ class MetadataSearch: def _on_youtube_for_type_query(self, query): logger.debug("Extracting YouTube metadata for input track query.") - videos = self.providers["youtube"].search(query) - if not videos: - raise NoYouTubeVideoFoundError( - 'YouTube returned no videos for the search query "{}".'.format(query) - ) - if self.yt_manual: - youtube_video = prompt_for_youtube_search_result(videos) - else: - youtube_video = videos.bestmatch() - if youtube_video is None: - raise NoYouTubeVideoMatchError( - 'No matching videos found on YouTube for the search query "{}".'.format( - query - ) - ) + youtube_video = self._best_on_youtube_search_for_type_query(query) youtube_metadata = self.providers["youtube"].from_url(youtube_video["url"]) return youtube_metadata