forked from heqin-zhu/music-recover
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecrypt.py
129 lines (115 loc) · 4.38 KB
/
decrypt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#coding : utf-8
import os
import sys
import glob
import requests
DESDIR = '../cached_网易云音乐'
LRCDIR = os.path.join(DESDIR, 'lyric')
MSCDIR = os.path.join(DESDIR, 'music')
API = 'https://api.imjad.cn/cloudmusic/?'
# two args: id type
# type=song, lyric, comments, detail, artist, album, search
# eg API = 'https://api.imjad.cn/cloudmusic/?type=song&id=1234132' download music
hasModu = False
try:
from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
hasModu = True
except:
pass
class netease_music:
def __init__(self, path=''):
'''path is the direcoty that contains Music files(cached)'''
if path == '':
path = input('input the path of cached netease_music')
self.path = path
print('[+] Current Path: ' + path)
os.chdir(path)
self.files = glob.glob('*.uc') + glob.glob('*.uc!')
self.id_mp = {}
for i in self.files:
self.id_mp[self.getId(i)] = i
if not os.path.exists(DESDIR):
os.mkdir(DESDIR)
if not os.path.exists(LRCDIR):
os.mkdir(LRCDIR)
if not os.path.exists(MSCDIR):
os.mkdir(MSCDIR)
# import re
# self.nameXpath ='//div[@class="tit"]/em[@class="f-ff2"]/text()'
# self.lrcSentencePt=re.compile(r'\[\d+:\d+\.\d+\](.*?)\\n') # wrong (r'\[\d+,\d+\](\(\d+,\d+\)(\w))+\n')
def getId(self, name):
return name[:name.find('-')]
def getInfoFromWeb(self, musicId):
dic = {}
url = API+'type=detail&id=' + str(musicId)
info = requests.get(url).json()['songs'][0]
dic['artist'] = [info['ar'][0]['name']]
dic['title'] = [info['al']['name']]
dic['cover'] = [info['al']['picUrl']]
return dic
def getInfoFromFile(self, path):
if not os.path.exists(path):
print('Can not find file ' + path)
return {}
elif hasModu:
return dict(MP3(path, ID3=EasyID3))
else:
print('[Error] You can use pip3 to install mutagen or connet to the Internet')
raise Exception('Failed to get info of ' + path)
def genName(self, dic):
title = dic['title'][0]
artist = dic['artist'][0]
if artist in title:
title = title.replace(artist, '').strip()
return title + '--' + artist
def decrypt(self, fileName):
with open(fileName, 'rb') as f:
btay = bytearray(f.read())
musicId = self.getId(fileName)
idpath = os.path.join(MSCDIR, musicId + '.mp3')
if not os.path.exists(idpath):
with open(idpath, 'wb') as out:
for i, j in enumerate(btay):
btay[i] = j ^ 0xa3
out.write(bytes(btay))
dic = {}
try:
dic = self.getInfoFromWeb(musicId)
except Exception as e:
print(e)
print('正在尝试获取 MP3 文件的元数据 ')
dic = self.getInfoFromFile(os.path.join(MSCDIR, musicId))
name = self.genName(dic)
self.id_mp[musicId] = name
path = os.path.join(MSCDIR, name + '.mp3').replace(u'\u200b/\u200b', '')
if os.path.exists(idpath):
if os.path.exists(path):
os.remove(idpath)
else:
os.rename(idpath, path)
return musicId
def getLyric(self, musicId):
name = self.id_mp[musicId]
# 'http://music.163.com/api/song/lyric?id='
url = API + 'type=lyric&id=' + str(musicId)
try:
lrc = requests.get(url).json()
file = os.path.join(LRCDIR, name + '.lrc').replace(u'\u200b/\u200b', '')
if not os.path.exists(file):
with open(file, 'w', encoding='utf8') as f:
f.write(str(lrc))
except Exception as e:
print(e, ' Failed to get lyric of music '+name)
def getMusic(self):
for ct, i in enumerate(self.files):
musicId = self.decrypt(i)
print('[Music {}]'.format(ct+1).ljust(12)+self.id_mp[musicId])
self.getLyric(musicId)
if __name__ == '__main__':
if len(sys.argv) > 1:
path = sys.argv[1].strip()
else:
path = os.path.join(os.getcwd(), '')
handler = netease_music(path)
handler.getMusic()