From ca57f6c2bb1fccf5f94bfcd5a78a2c8a92ed6da9 Mon Sep 17 00:00:00 2001 From: Theodicy1 Date: Thu, 5 May 2022 20:27:35 -0500 Subject: [PATCH] added ytmusicapi support Now able to instantly upload downloaded music from bandcamp to YouTube Music --- .gitignore | 1 + CHANGELOG.md | 13 ++++++++++ README.md | 48 +++++++++++++++++++++++------------- bandcampdl/__init__.py | 1 + bandcampdl/objects.py | 10 +++++--- bandcampdl/pathdir.py | 2 +- bandcampdl/youtube_music.py | 16 ++++++++++++ main.py | 18 ++++++++++++-- requirements.txt | Bin 130 -> 170 bytes test.py | 11 +++++---- 10 files changed, 91 insertions(+), 29 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 bandcampdl/youtube_music.py diff --git a/.gitignore b/.gitignore index bee8a64..cfbae41 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +headers_auth.json \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3c0166f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Change Log +--- +## v1.0.0 - April 23, 2022 +Initial release + +- Script which downloads song or album from bandcamp + +## v1.0.1 - May 5, 2022 +YouTube music upload support + + +- ytmusicapi support +- upload_songs() method in youtube_music.py \ No newline at end of file diff --git a/README.md b/README.md index 233a4a1..673008c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # bandcamp-download -Script which downloads Bandcamp albums and songs in mp3 format. MP3 Files come with ID3 metadata. +Simple script which downloads Bandcamp albums and songs in mp3 format. MP3 Files come with ID3 metadata. + +Uses ytmusicapi to instantly upload songs to Youtube Music after downloading. -The downsides of downloading mp3s off the internet instead of using a mainstream music player is no more! ID3 Album cover, title, year, album artist... bandcamp-download will take care of it! # The Script in Action ### Running the script @@ -17,7 +18,7 @@ Downloading... Piano Sonata No.1 in C-Major, K. 279- III. Allegro Downloading... Piano Sonata No.2 in F-Major, K. 280- I. Allegro Assai Downloading... Piano Sonata No.2 in F-Major, K. 280- II. Adagio Downloading... Piano Sonata No.2 in F-Major, K. 280- III. Presto - +Success! ... ``` @@ -27,17 +28,22 @@ Downloading... Piano Sonata No.2 in F-Major, K. 280- III. Presto ### Correct ID3 metadata

-# Setup -1) Install the project zip and extract it. Call it bandcampdownload -2) Create a virtualenv if needed - +### Uploading to YoutTube Music using ytmusicapi ```powershell -py -m venv env - -.\env\Scripts\activate +Uploading... Piano Sonata No.1 in C-Major, K. 279- I. Allegro +Uploading... Piano Sonata No.1 in C-Major, K. 279- II. Andante +Uploading... Piano Sonata No.1 in C-Major, K. 279- III. Allegro +Uploading... Piano Sonata No.2 in F-Major, K. 280- I. Allegro Assai +Uploading... Piano Sonata No.2 in F-Major, K. 280- II. Adagio +Uploading... Piano Sonata No.2 in F-Major, K. 280- III. Presto +Success! ``` -3) Go to the project directory and enter: +# Setup +1) Install the project zip +2) Create a virtualenv if needed + +3) Install the requirements in the project directory ```powershell pip install -r requirements.txt @@ -49,15 +55,20 @@ pip install -r requirements.txt MUSIC_DIRECTORY = "C:\Music" # Default directory ``` -5) run `main.py` +5) run `main.py` and enter a bandcamp link ```powershell -cd .\bandcampdownload\ - python main.py ``` -6) Enter the bandcamp link containing the song or album you want to install -7) New album or song folder will now be where you set ```MUSIC_DIRECTORY``` + +6) New album or song folder will now be where you set ```MUSIC_DIRECTORY``` + +# Uploading to Youtube Music +1) Follow the setup steps to setup using the ytmusicapi documentation + +2) Enter the `headers_auth.json` path into YTMusic class in `youtube_music.py` + +3) Use the `upload_music()` method in `youtube_music.py` # To Do ✅ Download the album cover to directory folder alongside the MP3s @@ -70,12 +81,15 @@ python main.py ✅ Error handling +✅ YouTube Music Upload using ytmusicapi + - [ ] Refactoring -- [ ] PyQT + # Credits +- [ytmusicapi](https://github.com/sigma67/ytmusicapi) - Made for educational purposes - Support bandcamp artists! diff --git a/bandcampdl/__init__.py b/bandcampdl/__init__.py index ea80db0..91c9d83 100644 --- a/bandcampdl/__init__.py +++ b/bandcampdl/__init__.py @@ -2,3 +2,4 @@ from bandcampdl.objects import downloader from bandcampdl.objects import meta_info from bandcampdl.pathdir import PATH +from bandcampdl.youtube_music import YTM_upload diff --git a/bandcampdl/objects.py b/bandcampdl/objects.py index 6117d3f..646ca6b 100644 --- a/bandcampdl/objects.py +++ b/bandcampdl/objects.py @@ -121,7 +121,7 @@ class downloader(meta_info): '''downloads the mp3 of every link in the song_list ''' def __init__(self, link, directory): super().__init__(link) - self.directory = f'{directory}\{meta_info.get_title(self)}' + self.directory = f'{directory}/{meta_info.get_title(self)}' print("Getting MP3 links...") self.download_list = linkfinder.get_links(self) @@ -134,14 +134,14 @@ def download(self): print(f'{self.directory} already exists ') print(f'Getting album cover from: {meta_info.get_cover(self)}') - with open(f'{self.directory}\cover.jpg', 'wb') as f: # adding album cover to album/song directory folder + with open(f'{self.directory}/cover.jpg', 'wb') as f: # adding album cover to album/song directory folder cover_response = requests.get(meta_info.get_cover(self)) f.write(cover_response.content) print(f"Downloading Album: {meta_info.get_title(self)}") for i in range(len(self.download_list)): - filepath = f"{self.directory}\{list(meta_info.get_trackname(self))[i]}" + filepath = f"{self.directory}/{list(meta_info.get_trackname(self))[i]}" filename = f"{filepath}.mp3" track = self.download_list[i].strip('"') response = requests.get(track) @@ -165,7 +165,7 @@ def download(self): meta.save(filename) - with open(f'{self.directory}\cover.jpg', 'rb') as albumart: # Adding album cover to the ID3 + with open(f'{self.directory}/cover.jpg', 'rb') as albumart: # Adding album cover to the ID3 meta['APIC'] = APIC( encoding=3, mime='image/jpeg', @@ -177,6 +177,8 @@ def download(self): print("Success!") + return self.directory # returns the music album folder so we access the mp3 files + diff --git a/bandcampdl/pathdir.py b/bandcampdl/pathdir.py index fb9afdb..806ed76 100644 --- a/bandcampdl/pathdir.py +++ b/bandcampdl/pathdir.py @@ -1 +1 @@ -PATH = "C:\Music" # default path \ No newline at end of file +PATH = "C:/Music" # default path \ No newline at end of file diff --git a/bandcampdl/youtube_music.py b/bandcampdl/youtube_music.py new file mode 100644 index 0000000..37be543 --- /dev/null +++ b/bandcampdl/youtube_music.py @@ -0,0 +1,16 @@ +from ytmusicapi import YTMusic +from os import listdir + +class YTM_upload(): + '''Class which deals with YT Music api uploads''' + def __init__(self): + self.ytmusic = YTMusic("headers_auth.json") # Place the path to your headers_auth.json here + + def upload_songs(self, album_folder): + for song in listdir(album_folder): + if ".mp3" in song: # Makes sure non mp3 files do not get uploaded + print(f"Uploading... {song}") + self.ytmusic.upload_song(f"{album_folder}/{song}") + + print("Success!") + diff --git a/main.py b/main.py index 706e2fb..726f6c5 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,28 @@ import bandcampdl import sys + sys.stdout.reconfigure(encoding='utf-8') # Fixes git bash crashes -# Customize the main function however you like by using the methods found in objects.py +# Customize the main function however you like by using the methods found in objects.py or youtube_music.py # This main() function downloads songs taken from bandcamp and adds the corresponding metadata to each one def main(): + ''' Customize the main function however you like by using the methods found in objects.py or youtube_music.py + This main() function downloads songs taken from bandcamp and adds the corresponding metadata to each one. + + It also can upload the songs to YTMusic if ytmusicapi setup is followed. + ''' + link = input("Enter Bandcamp link: ") dl = bandcampdl.downloader(link, bandcampdl.PATH) - dl.download() + + # dl.download downloads the songs from the inputted link + album_folder = dl.download() + + # Remove this if you do not want to upload songs to YT Music + #u1 = bandcampdl.YTM_upload() + #u1.upload_songs(album_folder) + if __name__ == "__main__": main() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 9dbc61dc314437049e1cd6c246116409cdeff875..21510ea482646b9603ca21379e801cd0184e1f84 100644 GIT binary patch delta 47 ycmZo-T*Ww{Nu!dXgdvxql%bd*lOdTQk)Z%cD=^qG*aArd20aEN216iezyJUQY6yz} delta 6 NcmZ3**u*%Y2>=JQ0zm)( diff --git a/test.py b/test.py index 6f12ded..4552db4 100644 --- a/test.py +++ b/test.py @@ -1,12 +1,13 @@ #File for testing functions import requests from bs4 import BeautifulSoup - -string = "//" - -print(string.isalnum()) +from ytmusicapi import YTMusic def badchar(self, string): # Removes illegal filename characters for c in '\/:*?"<>|': string = string.replace(c,'-') - return string; \ No newline at end of file + return string; + + +ytmusic = YTMusic("headers_auth.json") +