mirror of
https://github.com/TeamPGM/PagerMaid_Plugins.git
synced 2024-11-25 06:27:42 +00:00
重要更新!NeteaseMusic支持解锁VIP歌曲并且解除地区限制
This commit is contained in:
parent
03f5fcaf45
commit
ce070ecb02
@ -282,10 +282,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "neteasemusic",
|
"name": "neteasemusic",
|
||||||
"version": "1.4",
|
"version": "1.5",
|
||||||
"section": "daily",
|
"section": "daily",
|
||||||
"maintainer": "TNTcraftHIM",
|
"maintainer": "TNTcraftHIM",
|
||||||
"size": "21.6 kb",
|
"size": "22.3 kb",
|
||||||
"supported": true,
|
"supported": true,
|
||||||
"des-short": "网易云点歌",
|
"des-short": "网易云点歌",
|
||||||
"des": "可以在线搜索并且快速点歌,歌曲信息齐全,支持直接回复点歌。命令:nem。"
|
"des": "可以在线搜索并且快速点歌,歌曲信息齐全,支持直接回复点歌。命令:nem。"
|
||||||
|
@ -15,7 +15,8 @@ from collections import defaultdict
|
|||||||
|
|
||||||
songid = ''
|
songid = ''
|
||||||
name = ''
|
name = ''
|
||||||
|
proxies = {}
|
||||||
|
proxynum = 0
|
||||||
|
|
||||||
@listener(is_plugin=True, outgoing=True, command="nem",
|
@listener(is_plugin=True, outgoing=True, command="nem",
|
||||||
description="网易云搜/点歌。",
|
description="网易云搜/点歌。",
|
||||||
@ -23,8 +24,11 @@ name = ''
|
|||||||
async def nem(context):
|
async def nem(context):
|
||||||
global name
|
global name
|
||||||
global songid
|
global songid
|
||||||
|
global proxies
|
||||||
|
global proxynum
|
||||||
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063',
|
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063',
|
||||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","X-Real-IP": "223.252.199.66"}
|
||||||
|
proxy=[{'http': 'http://xbmmw.xyz:1001', 'https': 'http://xbmmw.xyz:1001'},{'http': 'http://music.lolico.me:39000', 'https': 'http://music.lolico.me:39000'},{'http': 'http://aimer.one:2333', 'https': 'http://aimer.one:2333'}]
|
||||||
if len(context.parameter) < 2:
|
if len(context.parameter) < 2:
|
||||||
await context.edit("使用方法:`-nem` `<指令>` `<关键词>`\n(指令s为搜索,指令p为播放\n关键词可填歌曲ID,或直接回复搜索结果 `-nem` `p` `<歌曲数字序号>`)")
|
await context.edit("使用方法:`-nem` `<指令>` `<关键词>`\n(指令s为搜索,指令p为播放\n关键词可填歌曲ID,或直接回复搜索结果 `-nem` `p` `<歌曲数字序号>`)")
|
||||||
return
|
return
|
||||||
@ -34,7 +38,7 @@ async def nem(context):
|
|||||||
keyword += context.parameter[i] + " "
|
keyword += context.parameter[i] + " "
|
||||||
keyword = keyword[:-1]
|
keyword = keyword[:-1]
|
||||||
if context.parameter[0] == "s": # 搜索功能
|
if context.parameter[0] == "s": # 搜索功能
|
||||||
await context.edit("搜索中 . . .")
|
await context.edit(f"【{keyword}】搜索中 . . .")
|
||||||
url = "http://music.163.com/api/search/pc?&s=" + \
|
url = "http://music.163.com/api/search/pc?&s=" + \
|
||||||
keyword + "&offset=0&limit=5&type=1"
|
keyword + "&offset=0&limit=5&type=1"
|
||||||
for _ in range(20): # 最多尝试20次
|
for _ in range(20): # 最多尝试20次
|
||||||
@ -58,7 +62,7 @@ async def nem(context):
|
|||||||
for i in range(len(info)):
|
for i in range(len(info)):
|
||||||
text += f"#{i+1}: \n<strong>歌名</strong>: {info[i]['title']}\n"
|
text += f"#{i+1}: \n<strong>歌名</strong>: {info[i]['title']}\n"
|
||||||
if info[i]['alias']:
|
if info[i]['alias']:
|
||||||
text += f"<strong>别名</strong>: {info[i]['alias'][0]} \n"
|
text += f"<strong>别名</strong>: <i>{info[i]['alias'][0]}</i>\n"
|
||||||
if info[i]['album']:
|
if info[i]['album']:
|
||||||
res = '<a href="' + \
|
res = '<a href="' + \
|
||||||
info[i]['albumpic'] + '">' + \
|
info[i]['albumpic'] + '">' + \
|
||||||
@ -125,6 +129,10 @@ async def nem(context):
|
|||||||
keyword + "&offset=0&limit=1&type=1"
|
keyword + "&offset=0&limit=1&type=1"
|
||||||
for _ in range(20): # 最多尝试20次
|
for _ in range(20): # 最多尝试20次
|
||||||
status = False
|
status = False
|
||||||
|
if proxynum > (len(proxy) -1): #代理自动切换至下一个
|
||||||
|
proxynum = 0
|
||||||
|
proxies = proxy[proxynum]
|
||||||
|
proxynum += 1
|
||||||
req = requests.request("GET", url, headers=headers)
|
req = requests.request("GET", url, headers=headers)
|
||||||
if req.status_code == 200:
|
if req.status_code == 200:
|
||||||
req = json.loads(req.content)
|
req = json.loads(req.content)
|
||||||
@ -162,7 +170,6 @@ async def nem(context):
|
|||||||
name = info['title'].replace('/', " ") + ".mp3"
|
name = info['title'].replace('/', " ") + ".mp3"
|
||||||
if ccimported: # 尝试使用高清音质下载
|
if ccimported: # 尝试使用高清音质下载
|
||||||
songid = str(info['id'])
|
songid = str(info['id'])
|
||||||
|
|
||||||
class WangyiyunDownload(object):
|
class WangyiyunDownload(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.key = '0CoJUm6Qyw8W8jud'
|
self.key = '0CoJUm6Qyw8W8jud'
|
||||||
@ -173,36 +180,31 @@ async def nem(context):
|
|||||||
# 请求头
|
# 请求头
|
||||||
self.headers = {
|
self.headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
|
||||||
# 这里需传入登录cookie,并且必须是会员账户才能访问会员曲目,否则只能访问免费曲目
|
# 传入登录cookie,
|
||||||
'Cookie': 'MUSIC_U=f52f220df171da480dbf33ce89947961585a7fdf08c89a2a4bdd6efebd86544233a649814e309366;',
|
'Cookie': 'MUSIC_U=f52f220df171da480dbf33ce89947961585a7fdf08c89a2a4bdd6efebd86544233a649814e309366;',
|
||||||
|
"X-Real-IP": "223.252.199.66",
|
||||||
}
|
}
|
||||||
# 请求url
|
# 请求url
|
||||||
self.url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='
|
self.url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='
|
||||||
|
|
||||||
# 生成16位随机数字符串
|
# 生成16位随机数字符串
|
||||||
# 对应的js --> a函数
|
|
||||||
def set_random_num(self):
|
def set_random_num(self):
|
||||||
random_num = ''
|
random_num = ''
|
||||||
# 从此字符串随机取出16个字符
|
# 随机取16个字符
|
||||||
string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
for i in range(16):
|
for ___ in range(16):
|
||||||
# random.uniform(0, 1) * len(string): 生成一个实数,范围在0 <= n < len(string)
|
|
||||||
# math.floor(n): 将n向下取整
|
|
||||||
n = math.floor(
|
n = math.floor(
|
||||||
random.uniform(0, 1) * len(string))
|
random.uniform(0, 1) * len(string))
|
||||||
# 从string中取出下标为n的字符拼接到random_num中
|
|
||||||
random_num += string[n]
|
random_num += string[n]
|
||||||
# 返回16位随机数字符串
|
# 返回16位随机数字符串
|
||||||
return random_num
|
return random_num
|
||||||
|
|
||||||
# 生成encSecKey
|
# 生成encSecKey
|
||||||
# 对应的js --> c函数
|
|
||||||
# 通过public_key和modulus对random_num进行RSA加密
|
# 通过public_key和modulus对random_num进行RSA加密
|
||||||
# random_num: 生成的16位随机数字符串
|
|
||||||
def RSA_encrypt(self, random_num):
|
def RSA_encrypt(self, random_num):
|
||||||
# 先将16位随机数字符串倒序并以utf-8编码
|
# 将16位随机数字符串倒序并以utf-8编码
|
||||||
random_num = random_num[::-1].encode('utf-8')
|
random_num = random_num[::-1].encode('utf-8')
|
||||||
# 然后再将其以hex(16进制)编码
|
# 将其以hex(16进制)编码
|
||||||
random_num = codecs.encode(
|
random_num = codecs.encode(
|
||||||
random_num, 'hex_codec')
|
random_num, 'hex_codec')
|
||||||
# 加密(三者均要从16进制转换为10进制)
|
# 加密(三者均要从16进制转换为10进制)
|
||||||
@ -215,7 +217,6 @@ async def nem(context):
|
|||||||
return encryption
|
return encryption
|
||||||
|
|
||||||
# 生成params
|
# 生成params
|
||||||
# 对应的js --> b函数
|
|
||||||
# 根据key和iv对msg进行AES加密,需调用两次
|
# 根据key和iv对msg进行AES加密,需调用两次
|
||||||
# key:
|
# key:
|
||||||
# 第一次: key
|
# 第一次: key
|
||||||
@ -245,13 +246,13 @@ async def nem(context):
|
|||||||
# 根据歌曲song_id,生成需要传输的data
|
# 根据歌曲song_id,生成需要传输的data
|
||||||
# 其中包括params和encSecKey
|
# 其中包括params和encSecKey
|
||||||
def construct_data(self, song_id):
|
def construct_data(self, song_id):
|
||||||
# 先生成16位随机数字符串
|
# 生成16位随机数字符串
|
||||||
random_num = self.set_random_num()
|
random_num = self.set_random_num()
|
||||||
# 生成encSecKey
|
# 生成encSecKey
|
||||||
encSecKey = self.RSA_encrypt(
|
encSecKey = self.RSA_encrypt(
|
||||||
random_num=random_num)
|
random_num=random_num)
|
||||||
# 调用两次AES加密生成params
|
# 调用两次AES加密生成params
|
||||||
# 先初始化歌曲song_info
|
# 初始化歌曲song_info
|
||||||
song_info = '{"ids":"[%s]","level":"exhigh","encodeType":"mp3","csrf_token":"477c1bd99fddedb3adc074f47fee2d35"}' % song_id
|
song_info = '{"ids":"[%s]","level":"exhigh","encodeType":"mp3","csrf_token":"477c1bd99fddedb3adc074f47fee2d35"}' % song_id
|
||||||
# 第一次加密,传入encText, key和iv
|
# 第一次加密,传入encText, key和iv
|
||||||
first_encryption = self.AES_encrypt(
|
first_encryption = self.AES_encrypt(
|
||||||
@ -297,6 +298,7 @@ async def nem(context):
|
|||||||
|
|
||||||
def download(self):
|
def download(self):
|
||||||
global name
|
global name
|
||||||
|
global proxies
|
||||||
# 获取下载链接
|
# 获取下载链接
|
||||||
real_url = self.get_real_url()
|
real_url = self.get_real_url()
|
||||||
if real_url == '':
|
if real_url == '':
|
||||||
@ -305,29 +307,33 @@ async def nem(context):
|
|||||||
file = name
|
file = name
|
||||||
# 开始下载
|
# 开始下载
|
||||||
content = requests.get(
|
content = requests.get(
|
||||||
url=real_url, headers=self.headers).content
|
url=real_url, headers=self.headers, proxies=proxies, verify=False).content
|
||||||
with open(file, 'wb') as fp:
|
with open(file, 'wb') as fp:
|
||||||
fp.write(content)
|
fp.write(content)
|
||||||
try:
|
for __ in range(3): #最多尝试3次
|
||||||
WangyiyunDownload().download()
|
try:
|
||||||
except:
|
WangyiyunDownload().download()
|
||||||
ccimported = False
|
ccimported = True
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
ccimported = False
|
||||||
|
continue
|
||||||
if not exists(name):
|
if not exists(name):
|
||||||
ccimported = False
|
ccimported = False
|
||||||
|
|
||||||
if ccimported is False: # 下载(普通音质)
|
if ccimported is False: # 下载(普通音质)
|
||||||
music = requests.request(
|
music = requests.request(
|
||||||
"GET", "http://music.163.com/api/song/enhance/download/url?&br=" + str(info['br']) + "&id=" + str(info['id']), headers=headers)
|
"GET", "http://music.163.com/api/song/enhance/download/url?&br=" + str(info['br']) + "&id=" + str(info['id']), headers=headers, proxies=proxies, verify=False)
|
||||||
if music.status_code == 200:
|
if music.status_code == 200:
|
||||||
music = json.loads(music.content)
|
music = json.loads(music.content)
|
||||||
if not music['data']['url']:
|
if not music['data']['url']:
|
||||||
music = requests.request(
|
music = requests.request(
|
||||||
"GET", "https://music.163.com/song/media/outer/url?id=" + str(info['id']) + ".mp3", headers=headers)
|
"GET", "https://music.163.com/song/media/outer/url?id=" + str(info['id']) + ".mp3", headers=headers, proxies=proxies, verify=False)
|
||||||
if music.status_code != 200:
|
if music.status_code != 200:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
music = requests.request(
|
music = requests.request(
|
||||||
"GET", music['data']['url'], headers=headers)
|
"GET", music['data']['url'], headers=headers, proxies=proxies, verify=False)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -353,7 +359,7 @@ async def nem(context):
|
|||||||
if imported is True:
|
if imported is True:
|
||||||
await context.edit(f"{title}信息导入中 . . .")
|
await context.edit(f"{title}信息导入中 . . .")
|
||||||
imagedata = requests.get(
|
imagedata = requests.get(
|
||||||
info['albumpic'], headers=headers).content
|
info['albumpic'], headers=headers, proxies=proxies, verify=False).content
|
||||||
tag = eyed3.load(name)
|
tag = eyed3.load(name)
|
||||||
tag.initTag()
|
tag.initTag()
|
||||||
tag = tag.tag
|
tag = tag.tag
|
||||||
@ -364,6 +370,13 @@ async def nem(context):
|
|||||||
tag.images.set(3, imagedata, "image/jpeg", u"Cover")
|
tag.images.set(3, imagedata, "image/jpeg", u"Cover")
|
||||||
tag.save(
|
tag.save(
|
||||||
name, version=eyed3.id3.ID3_DEFAULT_VERSION, encoding='utf-8')
|
name, version=eyed3.id3.ID3_DEFAULT_VERSION, encoding='utf-8')
|
||||||
|
br = ""
|
||||||
|
if imported is True:
|
||||||
|
br = "#" + str(eyed3.mp3.Mp3AudioFile(name).info.bit_rate[1]) + "kbps "
|
||||||
|
alias = ""
|
||||||
|
if info['alias']:
|
||||||
|
alias = "\n\n__" + info['alias'][0].replace(" ","__") + "__"
|
||||||
|
cap += "\n#NeteaseMusic " + br + alias
|
||||||
await context.edit(f"{title}上传中 . . .")
|
await context.edit(f"{title}上传中 . . .")
|
||||||
await context.client.send_file(
|
await context.client.send_file(
|
||||||
context.chat_id,
|
context.chat_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user