Skip to content

Instantly share code, notes, and snippets.

@imebeh
Created June 20, 2016 14:11
Show Gist options
  • Save imebeh/b707f5ed17fa076da320a09f07d0a04b to your computer and use it in GitHub Desktop.
Save imebeh/b707f5ed17fa076da320a09f07d0a04b to your computer and use it in GitHub Desktop.
add ID3 tag for google play music offline library @ android
# coding: utf-8
import sqlite3
from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC, error, PictureType, Encoding, TIT2, TALB, TPE1, TPE2, TCON, TDRC, TRCK, TPOS
import os
conn = sqlite3.connect(os.path.join(os.getcwd(), 'databases', 'music.db'))
curs = conn.cursor()
file_map = {}
def cache_cover_map():
global file_map, curs
files = curs.execute('select RemoteLocation, LocalLocation from ARTWORK_CACHE').fetchall()
for f in files:
file_map.update({
f[0]: f[1]
})
def get_cover_file(art_url):
global file_map
if art_url not in file_map:
return None
else:
path_file = convert_local_path(file_map[art_url], 'cover')
if os.path.exists(path_file):
return path_file
else:
return None
def convert_local_path(filename, path_type='mp3'):
if path_type == 'mp3':
return os.path.join(os.getcwd(), 'files', 'music', filename)
else:
return os.path.join(os.getcwd(), 'files', 'artwork', filename)
def set_id3(filename, attribute, cover=None):
audio = MP3(filename, ID3=ID3)
# add ID3 tag if it doesn't exist
try:
audio.add_tags()
except error:
pass
# remove all tags
audio.tags.clear()
# add cover
if cover is not None:
audio.tags.add(
APIC(
encoding=Encoding.UTF8,
mime=u'image/jpeg',
type=PictureType.COVER_FRONT,
desc=u'Cover',
data=open(cover, 'rb').read()
)
)
# add others
audio.tags.add(TIT2(encoding=Encoding.UTF8, text=attribute['Title']))
audio.tags.add(TPE1(encoding=Encoding.UTF8, text=attribute['Artist']))
audio.tags.add(TALB(encoding=Encoding.UTF8, text=attribute['Album']))
audio.tags.add(TPE2(encoding=Encoding.UTF8, text=attribute['AlbumArtist']))
audio.tags.add(TCON(encoding=Encoding.UTF8, text=attribute['Genre']))
audio.tags.add(TDRC(encoding=Encoding.UTF8, text=u'{}'.format(attribute['Year'])))
audio.tags.add(TRCK(encoding=Encoding.UTF8, text=u'{}'.format(attribute['TrackNumber'])))
audio.tags.add(TPOS(encoding=Encoding.UTF8, text=u'{}/{}'.format(attribute['DiscNumber'], attribute['DiscCount'])))
# save id3 v2.3, windows does not support v2.4
audio.save(v2_version=3)
cache_cover_map()
music = curs.execute(
'select LocalCopyPath,Title,Album,Artist,AlbumArtist,Genre,Year,TrackNumber,DiscCount,DiscNumber,'
'AlbumArtLocation from MUSIC'
).fetchall()
curs.close()
conn.close()
if music:
for one in music:
if one[0]:
p = convert_local_path(one[0])
# print '{}\t{}'.format(x[0], x[1])
if os.path.exists(p):
set_id3(
p,
dict(zip(['Title', 'Album', 'Artist', 'AlbumArtist', 'Genre', 'Year', 'TrackNumber', 'DiscCount',
'DiscNumber'], one[1:-1])),
get_cover_file(one[-1])
)
else:
print u'IGNORE: {}'.format(one[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment