I needed a way to copy the music that is stored locally on my Android device. I couldn't just copy the files over since they have nondescript names like 153.mp3, 214.mp3, etc. Well, I could have just copied them, but I didn't want to have to listen to all of them and then rename them appropriately. I could have downloaded them with Google Music Manager but there is a limit to the number of times you can download them (two, I think). But more importantly to me, I have a data cap and I have already downloaded them by selecting "Keep on device" and didn't want to download them again. What I did was use the music database to gather information and use that to copy and rename the files.
What is needed:
-a rooted device in order to access the music files
-adb installed on the PC (see here for info on adb)
-Python installed on the PC (although I imagine this could be done in a Bash script too)
-the Android device connected to the PC so adb can access it
A few notes:
-The music is copied to the current folder as Artist/Album/Tracks.
-Copying the MP3 files from the device can take a while. Patience is a virtue.
-The paths created are *nix style, i.e. uses forward slashes. Windows users might need to change to back slashes
-There isn't any error checking, so if adb fails or sqlite3 isn't installed, who knows what will happen?
Finally, here is the python script.
#!/usr/bin/python
# Extract locally stored music from Google Music and rename the files properly
# 12-08-2014 Created by Bill Blankenship
import subprocess
import sqlite3
import os
# Get a copy of the music database
subprocess.check_call(["adb", "pull", "/data/data/com.google.android.music/databases/music.db"])
subprocess.check_call(["adb", "pull", "/data/data/com.google.android.music/databases/music.db-journal"])
# Get the mp3 files
raw_input("Getting ready to copy mp3 files from the device. This can take a while.\nPress Ctl-C to abort or Enter to continue...")
subprocess.check_call(["adb", "pull", "/data/data/com.google.android.music/files/music/"])
# Get needed info from the database
db = sqlite3.connect("music.db")
cursor = db.cursor()
cursor.execute('''select Id, LocalCopyPath, Title, Album, Artist, TrackNumber from MUSIC where LocalCopyPath is not NULL''')
all_rows = cursor.fetchall()
# Iterate through each song
for row in all_rows:
# Replace "/" with "-" in track names 'cause they're trouble
# Apparently tuples are immutable, so create more variables
LocalPath = row[1].replace("/","-")
Title = row[2].replace("/","-")
Album = row[3].replace("/","-")
Artist = row[4].replace("/","-")
TrackNumber = row[5]
# Make TrackNumber two digits (and a string)
if TrackNumber < 10:
TrackNumber = "0"+str(TrackNumber)
else:
TrackNumber = str(TrackNumber)
# Create Artist folder if needed
if not os.path.isdir(Artist):
os.makedirs(Artist)
# Create Album folder if needed
if not os.path.isdir(Artist+"/"+Album):
os.makedirs(Artist+"/"+Album)
# Move and rename tracks
print("Copying "+LocalPath+" to "+Artist+"/"+Album+"/"+TrackNumber+"-"+Title+".mp3")
os.rename(LocalPath, Artist+"/"+Album+"/"+TrackNumber+"-"+Title+".mp3")
db.close()
# Remove the music database files
os.remove("music.db")
os.remove("music.db-journal")
No comments:
Post a Comment