Spaces:
Running
Running
import os | |
import re | |
import shutil | |
import requests | |
import gradio as gr | |
from mutagen.mp3 import MP3 | |
from mutagen.flac import FLAC | |
from mutagen.id3 import TIT2, TPE1, TALB | |
def insert_metadata(file_path: str, title, artist, album): | |
print(f"The file was successfully downloaded and saved to {file_path}") | |
try: | |
if file_path.endswith(".flac"): | |
audio = FLAC(file_path) | |
audio["TITLE"] = title | |
audio["ARTIST"] = artist | |
audio["ALBUM"] = album | |
else: | |
audio = MP3(file_path) | |
try: | |
audio.add_tags() | |
except Exception as e: | |
print(e) | |
audio.tags.add(TIT2(encoding=3, text=title)) | |
audio.tags.add(TPE1(encoding=3, text=artist)) | |
audio.tags.add(TALB(encoding=3, text=album)) | |
audio.save() | |
print(f"Metadata was successfully inserted into {file_path}") | |
except Exception as e: | |
print(f"An error occurred while processing {file_path}: {e}") | |
def download_file(id, quality, url, title, artist, album, cache="./__pycache__"): | |
if os.path.exists(cache): | |
shutil.rmtree(cache) | |
os.makedirs(cache) | |
format = "mp3" if " MP3" in quality else "flac" | |
local_filename = f"{cache}/{id}.{format}" | |
response = requests.get(url, stream=True) | |
if response.status_code == 200: | |
with open(local_filename, "wb") as file: | |
for chunk in response.iter_content(chunk_size=8192): | |
file.write(chunk) | |
insert_metadata(local_filename, title, artist, album) | |
return local_filename | |
else: | |
print(f"Download Failure, status code: {response.status_code}") | |
return url | |
def extract_fst_url(text): | |
url_pattern = r'(https?://[^\s"]+)' | |
match = re.search(url_pattern, text) | |
if match: | |
return match.group(1) | |
else: | |
return None | |
def get_real_url(short_url): | |
headers = { | |
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" | |
} | |
try: | |
response = requests.get( | |
short_url, | |
headers=headers, | |
allow_redirects=True, | |
timeout=10, | |
) | |
return response.url | |
except requests.exceptions.RequestException as e: | |
print(f"Error: {e}") | |
return None | |
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 | |
def infer(url: str, level: str): | |
song_id = parse_id(url) | |
if not song_id or not level: | |
return ( | |
None, | |
"Please input valid url or id and select a sound quality level!", | |
None, | |
None, | |
None, | |
None, | |
None, | |
None, | |
) | |
try: | |
response = requests.get( | |
os.getenv("api"), | |
params={"id": song_id, "type": "json", "level": level}, | |
) | |
if response.status_code == 200: | |
data = response.json()["data"] | |
return ( | |
download_file( | |
data["id"], | |
data["format"], | |
data["url"], | |
data["name"], | |
data["artist"], | |
data["album"], | |
), | |
data["name"], | |
data["pic"], | |
data["artist"], | |
data["album"], | |
data["format"], | |
data["size"], | |
data["lyric"], | |
) | |
except Exception as e: | |
return ( | |
None, | |
f"{e}", | |
None, | |
None, | |
None, | |
None, | |
None, | |
None, | |
) | |
if __name__ == "__main__": | |
gr.Interface( | |
fn=infer, | |
inputs=[ | |
gr.Textbox( | |
label="Please input music163 song ID or URL", | |
placeholder="https://music.163.com/#/song?id=", | |
), | |
gr.Dropdown( | |
choices=[ | |
"standard", | |
"exhigh", | |
"lossless", | |
"hires", | |
"sky", | |
"jyeffect", | |
"jymaster", | |
], | |
value="lossless", | |
label="Sound Quality", | |
), | |
], | |
outputs=[ | |
gr.Audio(label="Song", show_download_button=True), | |
gr.Textbox(label="Title", show_copy_button=True), | |
gr.Image(label="Cover", show_download_button=True), | |
gr.Textbox(label="Artist", show_copy_button=True), | |
gr.Textbox(label="Album", show_copy_button=True), | |
gr.Textbox(label="Quality", show_copy_button=True), | |
gr.Textbox(label="Size", show_copy_button=True), | |
gr.TextArea(label="Lyrics", show_copy_button=True), | |
], | |
title="Parse Music163 Songs without Loss", | |
description="This site does not provide any audio and video storage services, but only to provide the most basic resolution services", | |
flagging_mode="never", | |
).launch() | |