Spaces:
Running
Running
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, | |
) | |