From 014c6530d6e3ebd76d2b84444d1803381180f9a1 Mon Sep 17 00:00:00 2001 From: Jackson Taylor Date: Thu, 23 Mar 2023 08:16:40 -0400 Subject: Add get_library --- get_library | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ jamos | 2 + requirements.txt | 2 + 3 files changed, 135 insertions(+) create mode 100755 get_library diff --git a/get_library b/get_library new file mode 100755 index 0000000..db7e6ec --- /dev/null +++ b/get_library @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +import json +# Can't remember what I needed this for... Maybe checking if song already +# exists? +# import musicpd +import music_tag +import os +import youtube_dl +from ytmusicapi import YTMusic + +DEBUG = True + +# Includes the format characters +YOUTUBE_MUSIC_URL = "https://music.youtube.com/watch?v={}" + +""" +How the albums will be formatted +{ + 'id': { + 'name': '', + 'tracks': [ + { + 'id': '', + 'name': '' + } + ], + "thumbnail_url": '', + "is_thumbnail_downloaded": False, + "thumbnail_filename": '', + } +} +""" +ALBUMS = {} + + +def create_downloader(music_directory, cookies): + audio_options = { + 'format': 'mp3/bestaudio/best', + 'cookiefile': cookies, + 'outtmpl': os.path.join(music_directory, '%(title)s.%(ext)s'), + 'postprocessors': [ + { + 'key': 'FFmpegExtractAudio', + 'preferredcodec': 'mp3', + 'preferredquality': '192', + }, + {'key': 'FFmpegMetadata'}, + ], + 'writeinfojson': True, + 'quiet': not DEBUG + } + +def write_metadata_to_song_file(filename, metadata): + file = music_tag.load_file(filename) + + file['name'] = metadata['title'] + file['artist'] = metadata['artist'] + file['album'] = metadata['album'] + file['year'] = metadata['year'] + + file.save() + +if __name__ == "__main__": + app = YTMusic('../headers_auth.json') + song_limit = 25 + + all_raw_song_data = app.get_library_songs(limit=song_limit, order='a_to_z') + + if DEBUG: + with open('raw_song_data.json', 'w') as f: + f.write(json.dumps(all_raw_song_data)) + + all_parsed_songs = [] + for raw_song in all_raw_song_data: + song_id = raw_song['videoId'] + album_id = raw_song['album']['id'] + if album_id not in ALBUMS.keys(): + raw_album = app.get_album(album_id) + ALBUMS[album_id] = { + 'name': raw_album['title'], + 'tracks': [{'title': song['title'], 'id': song['videoId'], 'track_num': index + 1} for index, song in enumerate(raw_album['tracks'])], + 'year': raw_album['year'], + # TODO: Add thumbnail_url + } + + album = ALBUMS[album_id] + + track_num = None + for track in ALBUMS[album_id]['tracks']: + if track['id'] == song_id: + track_num = track['track_num'] + + parsed_song = { + 'id': raw_song['videoId'], + 'title': raw_song['title'], + 'artists': [artist['name'] for artist in raw_song['artists']], + 'album': raw_song['album']['name'], + 'track': track_num, + 'url': YOUTUBE_MUSIC_URL.format(raw_song['videoId']), + 'year': album['year'] + } + all_parsed_songs.append(parsed_song) + + if DEBUG: + with open('parsed_album_data.json', 'w') as f: + f.write(json.dumps({'albums': ALBUMS})) + + with open('parsed_song_data.json', 'w') as f: + f.write(json.dumps({'songs': all_parsed_songs})) + + + # music_directory = os.path.join(os.path.expanduser("~"), "Music") + music_directory = './music' + + # TODO: Can you use the cookies from YTMusic here + # cookies = os.path.join(os.path.expanduser("~"), "cookies.txt") + cookies = './cookies.txt' + ytdl = create_downloader(music_directory, cookies) + + failed_songs = [] + for song in all_parsed_songs: + try: + ytdl.extract_info(song['url'], download=True) + except Exception as ex: + print(ex) + print("Could not download: {}".format((song))) + failed_songs.append(song) + + files = get_all_files(music_directory) + + diff --git a/jamos b/jamos index cbe8fdd..8c8e2a8 100755 --- a/jamos +++ b/jamos @@ -8,6 +8,8 @@ import os from pathlib import Path import sys import youtube_dl +import ytmusicapi +import musicpd DEBUG = False diff --git a/requirements.txt b/requirements.txt index b62af13..8d307a9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ music-tag==0.4.3 youtube-dl==2021.6.6 +python-musicpd==0.8.0 +ytmusicapi==0.25.0 -- cgit v1.2.3