music_parsers / modules /netease.py
admin
fix qmusic & kuwo
a3f92d6
raw
history blame
6.3 kB
import re
import requests
import gradio as gr
from tqdm import tqdm
from utils import (
extract_fst_url,
get_real_url,
insert_meta,
clean_dir,
timestamp,
API_163,
TIMEOUT,
TMP_DIR,
EN_US,
)
ZH2EN = {
"请输入网易云音乐 ID 或 URL 链接": "Please input music163 song ID or URL",
"选择音质": "Sound quality",
"标准音质": "standard",
"极高音质": "exhigh",
"无损音质": "lossless",
"Hires音质": "hires",
"沉浸环绕声": "sky",
"高清环绕声": "jyeffect",
"超清母带": "jymaster",
"含元信息音频下载": "Audio with metadata",
"歌名": "Title",
"作者": "Artist",
"专辑": "Album",
"歌词": "Lyrics",
"歌曲图片": "Cover",
"歌曲 ID": "Song ID",
"音质": "Quality",
"大小": "Size",
"网易云音乐无损解析": "Parse Music163 Songs without Loss",
"状态栏": "Status",
}
def _L(zh_txt: str):
return ZH2EN[zh_txt] if EN_US else zh_txt
def download_audio(
id: int,
quality: str,
url: str,
title: str,
artist: str,
album: str,
lyric: str,
cover: str,
cache=f"{TMP_DIR}/163",
):
clean_dir(cache)
fmt = "mp3" if " MP3" in quality else "flac"
local_file = f"{cache}/{id}.{fmt}"
response = requests.get(url, stream=True)
if response.status_code == 200:
total_size = int(response.headers.get("Content-Length", 0)) + 1
time_stamp = timestamp()
progress_bar = tqdm(
total=total_size,
unit="B",
unit_scale=True,
desc=f"[{time_stamp}] {local_file}",
)
with open(local_file, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk: # 确保 chunk 不为空
f.write(chunk) # 更新进度条
progress_bar.update(len(chunk))
return insert_meta(local_file, title, artist, album, lyric, cover)
else:
raise ConnectionError(f"下载失败,状态码:{response.status_code}")
def parse_id(url: str):
if not url:
return None
if url.isdigit():
return int(url)
url = extract_fst_url(url)
if not url:
return None
if url.startswith("http://163cn.tv/"):
url = get_real_url(url)
match = re.search(r"id=(\d+)", url)
if match:
return int(match.group(1))
else:
return None
# outer func requires try except
def infer(url: str, lv: str):
status = "Success"
if not lv:
lv = _L("无损音质")
song = title = cover = artist = album = quality = size = lyric = None
try:
song_id = parse_id(url)
if "playlist?" in url:
raise ValueError("请输入歌曲链接而非歌单链接!")
if not song_id or not lv:
raise ValueError("请输入有效的网址或 ID, 并选择一个声音质量水平!")
response = requests.get(
API_163,
params={
"id": song_id,
"type": "json",
"level": lv if EN_US else ZH2EN[lv],
},
timeout=TIMEOUT,
)
if response.status_code == 200:
data = response.json()["data"]
url = data["url"]
if extract_fst_url(url):
title = data["name"]
artist = data["artist"]
album = data["album"]
lyric = data["lyric"]
cover = data["pic"]
quality = data["format"]
size = data["size"]
song = download_audio(
data["id"],
quality,
url,
title,
artist,
album,
lyric,
cover,
)
else:
raise ValueError(f"{url}或歌曲不存在")
else:
raise ConnectionError(f"HTTP {response.status_code}")
except Exception as e:
status = f"{e}"
return status, song, title, artist, album, lyric, cover, song_id, quality, size
def parser163():
return gr.Interface(
fn=infer,
inputs=[
gr.Textbox(
label=_L("请输入网易云音乐 ID 或 URL 链接"),
placeholder="https://music.163.com/#/song?id=",
),
gr.Dropdown(
choices=[
_L("标准音质"),
_L("极高音质"),
_L("无损音质"),
_L("Hires音质"),
_L("沉浸环绕声"),
_L("高清环绕声"),
_L("超清母带"),
],
value=_L("无损音质"),
label=_L("选择音质"),
),
],
outputs=[
gr.Textbox(label=_L("状态栏"), show_copy_button=True),
gr.Audio(
label=_L("含元信息音频下载"),
show_download_button=True,
show_share_button=False,
),
gr.Textbox(label=_L("歌名"), show_copy_button=True),
gr.Textbox(label=_L("作者"), show_copy_button=True),
gr.Textbox(label=_L("专辑"), show_copy_button=True),
gr.TextArea(label=_L("歌词"), show_copy_button=True),
gr.Image(label=_L("歌曲图片"), show_share_button=False),
gr.Textbox(label=_L("歌曲 ID"), show_copy_button=True),
gr.Textbox(label=_L("音质"), show_copy_button=True),
gr.Textbox(label=_L("大小"), show_copy_button=True),
],
title=_L("网易云音乐无损解析"),
flagging_mode="never",
examples=[
["36990266", _L("标准音质")],
["http://163cn.tv/CmHfO44", _L("标准音质")],
["https://music.163.com/#/song?id=36990266", _L("标准音质")],
["https://y.music.163.com/m/song?id=36990266", _L("极高音质")],
[
"分享Alan Walker的单曲《Faded》http://163cn.tv/CmHfO44 (@网易云音乐)",
_L("无损音质"),
],
],
cache_examples=False,
)