mirror of
https://github.com/Suxiaoqinx/Netease_url.git
synced 2025-07-14 05:12:21 +08:00
添加GUI WEB界面
This commit is contained in:
parent
cb58a808a1
commit
00369dc92c
191
maingui.py
Normal file
191
maingui.py
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
from flask import Flask, request, render_template, jsonify, Response
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import urllib.parse
|
||||||
|
from hashlib import md5
|
||||||
|
from random import randrange
|
||||||
|
import requests
|
||||||
|
from cryptography.hazmat.primitives import padding
|
||||||
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import StringField, SelectField, SubmitField
|
||||||
|
from wtforms.validators import DataRequired
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config['SECRET_KEY'] = 'your_secret_key'
|
||||||
|
|
||||||
|
# 定义表单类
|
||||||
|
class SongForm(FlaskForm):
|
||||||
|
song_ids = StringField('Song ID or URL', validators=[DataRequired()])
|
||||||
|
level = SelectField('Quality Level', choices=[
|
||||||
|
('standard', '标准音质'),
|
||||||
|
('exhigh', '极高音质'),
|
||||||
|
('lossless', '无损音质'),
|
||||||
|
('hires', 'Hires音质'),
|
||||||
|
('sky', '沉浸环绕声'),
|
||||||
|
('jyeffect', '高清环绕声'),
|
||||||
|
('jymaster', '超清母带'),
|
||||||
|
], validators=[DataRequired()])
|
||||||
|
submit = SubmitField('Submit')
|
||||||
|
|
||||||
|
def HexDigest(data):
|
||||||
|
return "".join([hex(d)[2:].zfill(2) for d in data])
|
||||||
|
|
||||||
|
def HashDigest(text):
|
||||||
|
HASH = md5(text.encode("utf-8"))
|
||||||
|
return HASH.digest()
|
||||||
|
|
||||||
|
def HashHexDigest(text):
|
||||||
|
return HexDigest(HashDigest(text))
|
||||||
|
|
||||||
|
def parse_cookie(text: str):
|
||||||
|
cookie_ = [item.strip().split('=', 1) for item in text.strip().split(';') if item]
|
||||||
|
cookie_ = {k.strip(): v.strip() for k, v in cookie_}
|
||||||
|
return cookie_
|
||||||
|
|
||||||
|
def ids(ids):
|
||||||
|
if '163cn.tv' in ids:
|
||||||
|
response = requests.get(ids, allow_redirects=False)
|
||||||
|
ids = response.headers.get('Location')
|
||||||
|
if 'music.163.com' in ids:
|
||||||
|
index = ids.find('id=') + 3
|
||||||
|
ids = ids[index:].split('&')[0]
|
||||||
|
return ids
|
||||||
|
|
||||||
|
def read_cookie():
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
cookie_file = os.path.join(script_dir, 'cookie.txt')
|
||||||
|
with open(cookie_file, 'r') as f:
|
||||||
|
cookie_contents = f.read()
|
||||||
|
return cookie_contents
|
||||||
|
|
||||||
|
def post(url, params, cookie):
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/2.10.2.200154',
|
||||||
|
'Referer': '',
|
||||||
|
}
|
||||||
|
cookies = {
|
||||||
|
"os": "pc",
|
||||||
|
"appver": "",
|
||||||
|
"osver": "",
|
||||||
|
"deviceId": "pyncm!"
|
||||||
|
}
|
||||||
|
cookies.update(cookie)
|
||||||
|
response = requests.post(url, headers=headers, cookies=cookies, data={"params": params})
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
def size(value):
|
||||||
|
units = ["B", "KB", "MB", "GB", "TB", "PB"]
|
||||||
|
size = 1024.0
|
||||||
|
for i in range(len(units)):
|
||||||
|
if (value / size) < 1:
|
||||||
|
return "%.2f%s" % (value, units[i])
|
||||||
|
value = value / size
|
||||||
|
return value
|
||||||
|
|
||||||
|
def music_level1(value):
|
||||||
|
if value == 'standard':
|
||||||
|
return "标准音质"
|
||||||
|
elif value == 'exhigh':
|
||||||
|
return "极高音质"
|
||||||
|
elif value == 'lossless':
|
||||||
|
return "无损音质"
|
||||||
|
elif value == 'hires':
|
||||||
|
return "Hires音质"
|
||||||
|
elif value == 'sky':
|
||||||
|
return "沉浸环绕声"
|
||||||
|
elif value == 'jyeffect':
|
||||||
|
return "高清环绕声"
|
||||||
|
elif value == 'jymaster':
|
||||||
|
return "超清母带"
|
||||||
|
else:
|
||||||
|
return "未知音质"
|
||||||
|
|
||||||
|
def url_v1(id, level, cookies):
|
||||||
|
url = "https://interface3.music.163.com/eapi/song/enhance/player/url/v1"
|
||||||
|
AES_KEY = b"e82ckenh8dichen8"
|
||||||
|
config = {
|
||||||
|
"os": "pc",
|
||||||
|
"appver": "",
|
||||||
|
"osver": "",
|
||||||
|
"deviceId": "pyncm!",
|
||||||
|
"requestId": str(randrange(20000000, 30000000))
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'ids': [id],
|
||||||
|
'level': level,
|
||||||
|
'encodeType': 'flac',
|
||||||
|
'header': json.dumps(config),
|
||||||
|
}
|
||||||
|
|
||||||
|
if level == 'sky':
|
||||||
|
payload['immerseType'] = 'c51'
|
||||||
|
|
||||||
|
url2 = urllib.parse.urlparse(url).path.replace("/eapi/", "/api/")
|
||||||
|
digest = HashHexDigest(f"nobody{url2}use{json.dumps(payload)}md5forencrypt")
|
||||||
|
params = f"{url2}-36cd479b6b5-{json.dumps(payload)}-36cd479b6b5-{digest}"
|
||||||
|
padder = padding.PKCS7(algorithms.AES(AES_KEY).block_size).padder()
|
||||||
|
padded_data = padder.update(params.encode()) + padder.finalize()
|
||||||
|
cipher = Cipher(algorithms.AES(AES_KEY), modes.ECB())
|
||||||
|
encryptor = cipher.encryptor()
|
||||||
|
enc = encryptor.update(padded_data) + encryptor.finalize()
|
||||||
|
params = HexDigest(enc)
|
||||||
|
response = post(url, params, cookies)
|
||||||
|
return json.loads(response)
|
||||||
|
|
||||||
|
def name_v1(id):
|
||||||
|
urls = "https://interface3.music.163.com/api/v3/song/detail"
|
||||||
|
data = {'c': json.dumps([{"id":id,"v":0}])}
|
||||||
|
response = requests.post(url=urls, data=data)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def lyric_v1(id, cookies):
|
||||||
|
url = "https://interface3.music.163.com/api/song/lyric"
|
||||||
|
data = {'id': id, 'cp': 'false', 'tv': '0', 'lv': '0', 'rv': '0', 'kv': '0', 'yv': '0', 'ytv': '0', 'yrv': '0'}
|
||||||
|
response = requests.post(url=url, data=data, cookies=cookies)
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
@app.route('/', methods=['GET', 'POST'])
|
||||||
|
def index():
|
||||||
|
form = SongForm()
|
||||||
|
return render_template('index.html', form=form)
|
||||||
|
|
||||||
|
@app.route('/fetch_data', methods=['POST'])
|
||||||
|
def fetch_data():
|
||||||
|
song_ids = request.form.get('song_ids')
|
||||||
|
level = request.form.get('level')
|
||||||
|
|
||||||
|
if not song_ids or not level:
|
||||||
|
return jsonify({"status": 400, "msg": "缺少参数!"})
|
||||||
|
|
||||||
|
cookies = parse_cookie(read_cookie())
|
||||||
|
song_id = ids(song_ids)
|
||||||
|
urlv1 = url_v1(song_id, level, cookies)
|
||||||
|
namev1 = name_v1(urlv1['data'][0]['id'])
|
||||||
|
lyricv1 = lyric_v1(urlv1['data'][0]['id'], cookies)
|
||||||
|
|
||||||
|
if urlv1['data'][0]['url'] is not None:
|
||||||
|
song_url = urlv1['data'][0]['url']
|
||||||
|
song_name = namev1['songs'][0]['name']
|
||||||
|
song_picUrl = namev1['songs'][0]['al']['picUrl']
|
||||||
|
song_alname = namev1['songs'][0]['al']['name']
|
||||||
|
artist_names = '/'.join(ar['name'] for ar in namev1['songs'][0]['ar'])
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"status": 200,
|
||||||
|
"name": song_name,
|
||||||
|
"pic": song_picUrl,
|
||||||
|
"ar_name": artist_names,
|
||||||
|
"al_name": song_alname,
|
||||||
|
"level": music_level1(urlv1['data'][0]['level']),
|
||||||
|
"size": size(urlv1['data'][0]['size']),
|
||||||
|
"url": song_url,
|
||||||
|
"lyric": lyricv1.get('lrc', {}).get('lyric', '无歌词'),
|
||||||
|
"tlyric": lyricv1.get('tlyric', {}).get('lyric', '无翻译歌词')
|
||||||
|
}
|
||||||
|
return jsonify(data)
|
||||||
|
return jsonify({"status": 400, "msg": "信息获取不完整!"})
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5000, debug=False)
|
Loading…
Reference in New Issue
Block a user