import requests from bs4 import BeautifulSoup import urllib.parse import re import json def get_bearer_token(): fetch_url = "https://open.spotify.com" response = requests.get(fetch_url) response.raise_for_status() # Check if the request was successful html_content = response.text soup = BeautifulSoup(html_content, 'html.parser') session_element = soup.find(id="session") session_html = session_element.get_text() tokens = json.loads(session_html) access_token = tokens['accessToken'] return access_token def search_spotify(artist, song): token = get_bearer_token() print("") print("Token:") print (token) print("") url = f'https://api.spotify.com/v1/search?query=artist%3A+{artist}+track%3A+{song}&type=track&offset=0&limit=1' headers = { 'Authorization': f'Bearer {token}' } response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() if data['tracks']['items']: href = data['tracks']['items'][0]['href'] match = re.search(r'tracks/([a-zA-Z0-9]+)', href) if match: song_id = match.group(1) return song_id else: raise ValueError("Song ID not found in the href.") else: raise ValueError("No tracks found for the given artist and song.") else: raise Exception(f"Spotify API request failed with status code {response.status_code}") def fetch_lyrics(track_id): url = f'https://beautiful-lyrics.socalifornian.live/lyrics/{track_id}' headers = { 'authorization': 'Bearer litterallyAnythingCanGoHereItJustTakesItLOL' } response = requests.get(url, headers=headers) if response.status_code == 200 and response.headers.get('content-length') != '0': return response.json() return None def convert_to_lrc_timestamp(timestamp): minutes = int(timestamp // 60) seconds = timestamp % 60 return f"{minutes:02}:{seconds:05.2f}" def parse_lyrics(data, useA2): lyrics = [] if data['Type'] == 'Line': for item in data['Content']: if item['Type'] == 'Vocal': line = item['Text'] timestamp = convert_to_lrc_timestamp(item['StartTime']) line = f"[{timestamp}] " + line lyrics.append(line.strip()) if 'Background' in item: print("This song has Background with Type Line, I was not able to find this in testing so I don't know the structure, please report this song, so I may add support for it.") elif data['Type'] == 'Syllable': if useA2: for item in data['Content']: if item['Type'] == 'Vocal': syllables = item['Lead']['Syllables'] line = '' timestamp = convert_to_lrc_timestamp(item['Lead']['StartTime']) for syllable in syllables: syllable_text = syllable['Text'] syllable_timestamp = convert_to_lrc_timestamp(syllable['StartTime']) if syllable['IsPartOfWord']: line += syllable_text else: line += f" <{syllable_timestamp}> {syllable_text}" line = f"[{timestamp}]" + line lyrics.append(line.strip()) if 'Background' in item: for bg in item['Background']: syllables = bg['Syllables'] line = '' timestamp = convert_to_lrc_timestamp(bg['StartTime']) for index, syllable in enumerate(syllables): syllable_text = syllable['Text'] syllable_timestamp = convert_to_lrc_timestamp(syllable['StartTime']) if syllable['IsPartOfWord']: if index == 0: line += f"({syllable_text}" elif index == len(syllables) - 1: line += f"{syllable_text})" else: line += syllable_text else: if index == 0: line += f" <{syllable_timestamp}> ({syllable_text}" elif index == len(syllables) - 1: line += f" <{syllable_timestamp}> {syllable_text})" else: line += f" <{syllable_timestamp}> {syllable_text}" line = f"[{timestamp}]" + line lyrics.append(line.strip()) else: for item in data['Content']: if item['Type'] == 'Vocal': line = ''.join([ f"{syllable['Text']}{' ' if not syllable['IsPartOfWord'] else ''}" for syllable in item['Lead']['Syllables'] ]) timestamp = item['Lead']['StartTime'] line = f"[{convert_to_lrc_timestamp(timestamp)}]" + f" {line}" lyrics.append(line.strip()) if 'Background' in item: for bg in item['Background']: line = ''.join([ f"{syllable['Text']}{' ' if not syllable['IsPartOfWord'] else ''}" for syllable in bg['Syllables'] ]) timestamp = item['Background'][0]['StartTime'] line = f"[{convert_to_lrc_timestamp(timestamp)}]" + f" ({line.rstrip()})" lyrics.append(line.strip()) return lyrics def print_lyrics(lyrics): for line in lyrics: print(line) def main(): artist = input("Enter Artist Name: ").strip() song = input("Enter Song Title: ").strip() useA2_input = input("Should use A2 extension (Enhanced LRC format) if available? ") if useA2_input.lower() in ['true', '1', 't', 'y', 'yes']: useA2 = True elif useA2_input.lower() in ['false', '0', 'f', 'n', 'no']: useA2 = False else: raise ValueError("Invalid input. Please enter True or False.") # Search Spotify and get track ID track_id = search_spotify(artist, song) if not track_id: print("No track found on Spotify.") return # Fetch lyrics using track ID data = fetch_lyrics(track_id) if not data: print("No lyrics found for this track.") return # Parse and print lyrics lyrics = parse_lyrics(data, useA2) print("") print("Lyrics:") print("") print_lyrics(lyrics) print("") if __name__ == "__main__": main()