File size: 5,376 Bytes
a3f92d6
4b11d55
 
 
b02246d
 
 
 
 
 
 
 
 
65004e0
b02246d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65004e0
4b11d55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a3f92d6
 
3e6dcd1
 
b02246d
4b11d55
 
3e6dcd1
 
4b11d55
 
3e6dcd1
 
4b11d55
 
 
 
 
b02246d
4b11d55
 
 
 
 
 
b02246d
4b11d55
b02246d
4b11d55
 
 
 
b02246d
4b11d55
 
 
 
bb58f2e
4b11d55
 
 
 
 
 
 
 
 
 
 
 
bb58f2e
4b11d55
 
 
 
 
 
a3f92d6
 
 
 
 
 
 
 
 
 
b02246d
 
a3f92d6
b02246d
 
 
 
 
 
 
a3f92d6
4b11d55
 
b02246d
4b11d55
 
b02246d
4b11d55
b02246d
4b11d55
 
 
 
 
 
 
b02246d
4b11d55
b02246d
4b11d55
 
b02246d
262568e
b02246d
262568e
 
 
b02246d
 
 
 
 
 
 
 
4b11d55
b02246d
4b11d55
 
 
 
b02246d
4b11d55
 
 
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import os
import re
import requests
import gradio as gr
from utils import (
    extract_fst_url,
    get_real_url,
    download_file,
    API_QQ_2,
    API_QQ_1,
    KEY_QQ_1,
    TIMEOUT,
    TMP_DIR,
    EN_US,
)

ZH2EN = {
    "请输入QQ音乐 mid 或 URL 链接": "Please enter the mid or URL of QQ music song",
    "含元信息音频下载": "Audio with metadata",
    "歌名": "Title",
    "作者": "Artist",
    "专辑": "Album",
    "歌词": "Lyrics",
    "歌曲图片": "Cover",
    "歌曲 ID": "Song ID",
    "音质": "Quality",
    "大小": "Size",
    "QQ音乐直链解析": "QQ Music Parser",
    "状态栏": "Status",
}


def _L(zh_txt: str):
    return ZH2EN[zh_txt] if EN_US else zh_txt


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 get_file_size(file_path):
    size_in_bytes = os.path.getsize(file_path)
    units = ["B", "KB", "MB", "GB"]  # 初始单位为字节
    unit_index = 0  # 根据文件大小选择合适的单位
    if size_in_bytes >= 1024**3:  # 大于等于 1 GB
        unit_index = 3
        size = size_in_bytes / (1024**3)
    # 大于等于 1 MB
    elif size_in_bytes >= 1024**2:
        unit_index = 2
        size = size_in_bytes / (1024**2)
    # 大于等于 1 KB
    elif size_in_bytes >= 1024:
        unit_index = 1
        size = size_in_bytes / 1024

    else:
        size = size_in_bytes
    # 格式化输出,保留两位小数
    if unit_index == 0:
        return f"{size}{units[unit_index]}"
    else:
        return f"{size:.2f}{units[unit_index]}"


# outer func requires try except
def infer(url: str):
    status = "Success"
    song = title = artist = album = lyric = cover = song_id = quality = size = None
    try:
        song_mid = parse_id(url)
        if not song_mid:
            raise ValueError("请输入有效的网址或mid!")

        # title, artist, album, cover
        response = requests.get(
            API_QQ_1,
            params={"key": KEY_QQ_1, "type": "song", "mid": song_mid},
            timeout=TIMEOUT,
        )
        if response.status_code == 200 and response.json()["code"] == 200:
            data = response.json()["data"]
            title = data["title"]
            artist = data["author"]
            album = data["album_title"]
            cover = str(data["pic"]).replace("300x300", "800x800").split("?max_age=")[0]

        # lyrics
        response = requests.get(
            API_QQ_1,
            params={"key": KEY_QQ_1, "type": "lrc", "mid": song_mid, "format": "json"},
            timeout=TIMEOUT,
        )
        if response.status_code == 200 and response.json()["code"] == 200:
            lyric = response.json()["data"]

        # url
        response = requests.get(
            API_QQ_2,
            params={"id": song_mid},
            timeout=TIMEOUT,
            verify=False,
        )
        if response.status_code == 200:
            url = response.json()["data"]
            song_id = song_mid
            quality = "128kb"
            song = download_file(
                song_mid,
                url,
                title,
                artist,
                album,
                lyric,
                cover,
                f"{TMP_DIR}/qq",
            )
            size = get_file_size(song)

        else:
            raise ConnectionError(response.json()["msg"] + ", 可能是歌曲mid或URL有误")

    except Exception as e:
        status = f"{e}"

    return status, song, title, artist, album, lyric, cover, song_id, quality, size


def qmusic_parser():
    return gr.Interface(
        fn=infer,
        inputs=[
            gr.Textbox(
                label=_L("请输入QQ音乐 mid 或 URL 链接"),
                placeholder="https://y.qq.com/n/ryqq/songDetail/*",
            )
        ],
        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("QQ音乐直链解析"),
        flagging_mode="never",
        examples=[
            "000ZjUoy0DeHRO",
            "https://y.qq.com/n/ryqq/songDetail/000ZjUoy0DeHRO",
            "DJMOUN《一氧化碳 (监狱兔概念神) (DJ版)》 https://c6.y.qq.com/base/fcgi-bin/u?__=fY3GHnkxtiHJ @QQ音乐",
        ],
        cache_examples=False,
    )