admin commited on
Commit
c550a79
·
1 Parent(s): 73a32fe
Files changed (4) hide show
  1. .gitignore +2 -0
  2. README.md +2 -2
  3. app.py +158 -0
  4. requirements.txt +1 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ test.*
2
+ *__pycache__*
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  title: Qmusic Parser
3
  emoji: ⚡
4
- colorFrom: blue
5
- colorTo: gray
6
  sdk: gradio
7
  sdk_version: 5.21.0
8
  app_file: app.py
 
1
  ---
2
  title: Qmusic Parser
3
  emoji: ⚡
4
+ colorFrom: yellow
5
+ colorTo: green
6
  sdk: gradio
7
  sdk_version: 5.21.0
8
  app_file: app.py
app.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import shutil
4
+ import requests
5
+ import gradio as gr
6
+ from mutagen.mp3 import MP3
7
+ from mutagen.flac import FLAC
8
+ from mutagen.id3 import TIT2, TPE1, TALB
9
+
10
+
11
+ def insert_metadata(file_path: str, title, artist, album):
12
+ print(f"The file was successfully downloaded and saved to {file_path}")
13
+ if file_path.endswith(".flac"):
14
+ audio = FLAC(file_path)
15
+ audio["TITLE"] = title
16
+ audio["ARTIST"] = artist
17
+ audio["ALBUM"] = album
18
+
19
+ else:
20
+ audio = MP3(file_path)
21
+ try:
22
+ audio.add_tags()
23
+ except Exception as e:
24
+ print(e)
25
+
26
+ audio.tags.add(TIT2(encoding=3, text=title))
27
+ audio.tags.add(TPE1(encoding=3, text=artist))
28
+ audio.tags.add(TALB(encoding=3, text=album))
29
+
30
+ audio.save()
31
+ print(f"Metadata was successfully inserted into {file_path}")
32
+
33
+
34
+ def download_file(id, url: str, title, artist, album, cache="./__pycache__"):
35
+ if os.path.exists(cache):
36
+ shutil.rmtree(cache)
37
+
38
+ os.makedirs(cache)
39
+ format = "mp3"
40
+ local_filename = f"{cache}/{id}.{format}"
41
+ response = requests.get(url, stream=True)
42
+ if response.status_code == 200:
43
+ with open(local_filename, "wb") as file:
44
+ for chunk in response.iter_content(chunk_size=8192):
45
+ file.write(chunk)
46
+
47
+ insert_metadata(local_filename, title, artist, album)
48
+ return local_filename
49
+
50
+ else:
51
+ print(f"Download Failure, status code: {response.status_code}")
52
+ return url
53
+
54
+
55
+ def extract_fst_url(text):
56
+ url_pattern = r'(https?://[^\s"]+)'
57
+ match = re.search(url_pattern, text)
58
+ if match:
59
+ return match.group(1)
60
+ else:
61
+ return None
62
+
63
+
64
+ def get_real_url(short_url):
65
+ return requests.get(
66
+ short_url,
67
+ headers={
68
+ "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"
69
+ },
70
+ allow_redirects=True,
71
+ timeout=10,
72
+ ).url
73
+
74
+
75
+ def parse_id(url: str):
76
+ if not url:
77
+ return None
78
+
79
+ if re.fullmatch(r"^[A-Za-z0-9]{14}$", url):
80
+ return str(url)
81
+
82
+ url = extract_fst_url(url)
83
+ if not url:
84
+ return None
85
+
86
+ if url.startswith("https://c6.y.qq.com/base/fcgi-bin/"):
87
+ return get_real_url(url).split("songmid=")[1].split("&")[0]
88
+
89
+ match = re.search(r"songDetail/([^?]+)", url)
90
+ if match:
91
+ return str(match.group(1))
92
+ else:
93
+ return None
94
+
95
+
96
+ def infer(url: str):
97
+ song = title = song_id = artist = album = quality = size = None
98
+ try:
99
+ song_mid = parse_id(url)
100
+ if not song_mid:
101
+ title = "Please enter a valid URL or mid!"
102
+ return song, title, song_id, artist, album, quality, size
103
+
104
+ response = requests.get(
105
+ os.getenv("api"),
106
+ params={"mid": song_mid},
107
+ )
108
+
109
+ if response.status_code == 200:
110
+ data = response.json()["data"]
111
+ song = download_file(
112
+ data["id"],
113
+ data["urls"][0]["url"],
114
+ data["title"],
115
+ data["author"],
116
+ data["album"],
117
+ )
118
+ title = data["title"]
119
+ song_id = data["id"]
120
+ artist = data["author"]
121
+ album = data["album"]
122
+ quality = data["urls"][0]["type"]
123
+ size = data["urls"][0]["size"]
124
+
125
+ except Exception as e:
126
+ title = f"{e}"
127
+
128
+ return song, title, song_id, artist, album, quality, size
129
+
130
+
131
+ if __name__ == "__main__":
132
+ gr.Interface(
133
+ fn=infer,
134
+ inputs=[
135
+ gr.Textbox(
136
+ label="Please enter the mid or URL of QQ music song",
137
+ placeholder="https://y.qq.com/n/ryqq/songDetail/*",
138
+ ),
139
+ ],
140
+ outputs=[
141
+ gr.Audio(label="Song download", show_download_button=True),
142
+ gr.Textbox(label="Title", show_copy_button=True),
143
+ gr.Textbox(label="Song ID", show_copy_button=True),
144
+ gr.Textbox(label="Artist", show_copy_button=True),
145
+ gr.Textbox(label="Album", show_copy_button=True),
146
+ gr.Textbox(label="Quality", show_copy_button=True),
147
+ gr.Textbox(label="Size", show_copy_button=True),
148
+ ],
149
+ title="QQ Music Parser",
150
+ description="This site does not provide any audio storage services, only provide the most basic parsing services",
151
+ flagging_mode="never",
152
+ examples=[
153
+ "003N68WJ0mh5jN",
154
+ "https://y.qq.com/n/ryqq/songDetail/003N68WJ0mh5jN",
155
+ "https://c6.y.qq.com/base/fcgi-bin/u?__=VfAFlMiujMhz",
156
+ ],
157
+ cache_examples=False,
158
+ ).launch()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ mutagen