Skip to content

Commit

Permalink
added ytmusicapi support
Browse files Browse the repository at this point in the history
Now able to instantly upload downloaded music from bandcamp to YouTube Music
  • Loading branch information
xxruyle committed May 6, 2022
1 parent b05a628 commit ca57f6c
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 29 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__pycache__
headers_auth.json
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
48 changes: 31 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -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 <a href="https://github.com/sigma67/ytmusicapi">ytmusicapi</a> 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
Expand All @@ -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!
...
```

Expand All @@ -27,17 +28,22 @@ Downloading... Piano Sonata No.2 in F-Major, K. 280- III. Presto
### Correct ID3 metadata
<p align='center'><img src='images\metadata.png' width='500' height='376.08'/>

# Setup
1) Install the project zip and extract it. Call it bandcampdownload
2) Create a virtualenv if needed

### Uploading to YoutTube Music using <a href="https://github.com/sigma67/ytmusicapi">ytmusicapi</a>
```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
Expand All @@ -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 <a href="https://ytmusicapi.readthedocs.io/en/latest/setup.html">ytmusicapi documentation</a>

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
Expand All @@ -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!
1 change: 1 addition & 0 deletions bandcampdl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 6 additions & 4 deletions bandcampdl/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand All @@ -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',
Expand All @@ -177,6 +177,8 @@ def download(self):

print("Success!")

return self.directory # returns the music album folder so we access the mp3 files




2 changes: 1 addition & 1 deletion bandcampdl/pathdir.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PATH = "C:\Music" # default path
PATH = "C:/Music" # default path
16 changes: 16 additions & 0 deletions bandcampdl/youtube_music.py
Original file line number Diff line number Diff line change
@@ -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!")

18 changes: 16 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -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()
Binary file modified requirements.txt
Binary file not shown.
11 changes: 6 additions & 5 deletions test.py
Original file line number Diff line number Diff line change
@@ -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;
return string;


ytmusic = YTMusic("headers_auth.json")

0 comments on commit ca57f6c

Please sign in to comment.