Spaces:
Running
Running
File size: 4,747 Bytes
c550a79 17c780d c550a79 17c780d c550a79 17c780d c550a79 17c780d c550a79 17c780d c550a79 17c780d c550a79 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
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}")
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}")
def download_file(mid: str, url: str, title, artist, album, cache="./__pycache__"):
if os.path.exists(cache):
shutil.rmtree(cache)
os.makedirs(cache)
local_filename = f"{cache}/{mid}.mp3"
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):
return requests.get(
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"
},
allow_redirects=True,
timeout=10,
).url
def parse_id(url: str):
if not url:
return None
if re.fullmatch(r"^[A-Za-z0-9]{14}$", url):
return str(url)
url = extract_fst_url(url)
if not url:
return None
if url.startswith("https://c6.y.qq.com/base/fcgi-bin/"):
return get_real_url(url).split("songmid=")[1].split("&")[0]
match = re.search(r"songDetail/([^?]+)", url)
if match:
return str(match.group(1))
else:
return None
def infer(url: str):
song = title = song_id = artist = album = quality = size = None
try:
song_mid = parse_id(url)
if not song_mid:
title = "Please enter a valid URL or mid!"
return song, title, song_id, artist, album, quality, size
response = requests.get(
os.getenv("api"),
params={"mid": song_mid},
)
if response.status_code == 200 and response.json()["code"] == 200:
data = response.json()["data"]
song = download_file(
data["mid"],
data["urls"][0]["url"],
data["title"],
data["author"],
data["album"],
)
title = data["title"]
song_id = data["id"]
artist = data["author"]
album = data["album"]
quality = data["urls"][0]["type"]
size = data["urls"][0]["size"]
else:
raise Exception(response.json()["msg"])
except Exception as e:
title = f"{e}"
return song, title, song_id, artist, album, quality, size
if __name__ == "__main__":
gr.Interface(
fn=infer,
inputs=[
gr.Textbox(
label="Please enter the mid or URL of QQ music song",
placeholder="https://y.qq.com/n/ryqq/songDetail/*",
),
],
outputs=[
gr.Audio(label="Song download", show_download_button=True),
gr.Textbox(label="Title", show_copy_button=True),
gr.Textbox(label="Song ID", show_copy_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(B)", show_copy_button=True),
],
title="QQ Music Parser",
description="This site does not provide any audio storage services, only provide the most basic parsing services",
flagging_mode="never",
examples=[
"003N68WJ0mh5jN",
"https://y.qq.com/n/ryqq/songDetail/003N68WJ0mh5jN",
"https://c6.y.qq.com/base/fcgi-bin/u?__=VfAFlMiujMhz",
],
cache_examples=False,
).launch()
|