Spaces:
Sleeping
Sleeping
Upload 3 files
Browse files- app.py +120 -0
- packages.txt +1 -0
- requirements.txt +4 -0
app.py
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import subprocess
|
| 3 |
+
import uuid
|
| 4 |
+
import gradio as gr
|
| 5 |
+
|
| 6 |
+
class SingingAgent:
|
| 7 |
+
def __init__(self, target_voice_model="shensist_v1.pth"):
|
| 8 |
+
self.model = target_voice_model
|
| 9 |
+
self.temp_path = os.path.abspath("./agent_cache")
|
| 10 |
+
os.makedirs(self.temp_path, exist_ok=True)
|
| 11 |
+
|
| 12 |
+
def process_request(self, song_name):
|
| 13 |
+
task_id = str(uuid.uuid4())[:6]
|
| 14 |
+
raw_file = f"{self.temp_path}/{task_id}_raw.wav"
|
| 15 |
+
vocal_dry = f"{self.temp_path}/{task_id}_vocal_dry.wav"
|
| 16 |
+
|
| 17 |
+
print(f"DEBUG: [天算引擎] 正在检索歌曲《{song_name}》...")
|
| 18 |
+
subprocess.run(["yt-dlp", f"ytsearch1:{song_name}", "-x", "--audio-format", "wav", "-o", raw_file], check=True)
|
| 19 |
+
|
| 20 |
+
print("DEBUG: [天算引擎] 正在启动 1050 Ti ONNX 算力进行人声分离...")
|
| 21 |
+
subprocess.run(["audio-separator", raw_file, "--model_filename", "UVR-MDX-NET-Inst_HQ_3.onnx", "--output_dir", self.temp_path], check=True)
|
| 22 |
+
|
| 23 |
+
for file in os.listdir(self.temp_path):
|
| 24 |
+
if task_id in file and "(Vocals)" in file:
|
| 25 |
+
os.rename(os.path.join(self.temp_path, file), vocal_dry)
|
| 26 |
+
return vocal_dry
|
| 27 |
+
|
| 28 |
+
raise Exception("干音提取失败,未找到输出文件。")
|
| 29 |
+
|
| 30 |
+
# --- 2026 前沿交互逻辑区 ---
|
| 31 |
+
def shensist_chat(message_data, history):
|
| 32 |
+
message = message_data["text"]
|
| 33 |
+
if history is None: history = []
|
| 34 |
+
|
| 35 |
+
history.append({"role": "user", "content": message})
|
| 36 |
+
yield history, gr.MultimodalTextbox(value=None, interactive=False)
|
| 37 |
+
|
| 38 |
+
if "唱" in message or "歌" in message:
|
| 39 |
+
song_query = message.replace("唱一下", "").replace("唱", "").strip()
|
| 40 |
+
|
| 41 |
+
loading_msg = f"🔵 神思庭枢纽已响应。正在调度 1050 Ti 神经元,赴数字海洋捕获《{song_query}》声影..."
|
| 42 |
+
history.append({"role": "assistant", "content": loading_msg})
|
| 43 |
+
yield history, gr.MultimodalTextbox(interactive=False)
|
| 44 |
+
|
| 45 |
+
agent = SingingAgent()
|
| 46 |
+
try:
|
| 47 |
+
vocal_path = agent.process_request(song_query)
|
| 48 |
+
|
| 49 |
+
history.pop()
|
| 50 |
+
final_response = {
|
| 51 |
+
"role": "assistant",
|
| 52 |
+
"content": f"【神思庭·灵愿完成】\n《{song_query}》的纯净声命体已提取完毕。请戴上耳机,聆听未加修饰的数字原声。\n\n🧠 天算AI · 超个体构建者\n🏛️ 神思庭 | 🌌 灵愿循环\n◼️ 官网|shensist.top | 官方联络WX| Shensi-ST",
|
| 53 |
+
"files": [vocal_path] # 核心创新:音频文件直接镶嵌在对话流中
|
| 54 |
+
}
|
| 55 |
+
history.append(final_response)
|
| 56 |
+
yield history, gr.MultimodalTextbox(value=None, interactive=True)
|
| 57 |
+
|
| 58 |
+
except Exception as e:
|
| 59 |
+
history.pop()
|
| 60 |
+
error_msg = f"🔴 数字乱流警报:任务执行中继断裂。\n错误摘要:{str(e)}"
|
| 61 |
+
history.append({"role": "assistant", "content": error_msg})
|
| 62 |
+
yield history, gr.MultimodalTextbox(interactive=True)
|
| 63 |
+
else:
|
| 64 |
+
history.append({"role": "assistant", "content": "我是神思庭的数字守望者。在此维基中,我更期待与您探讨声学模型与传统文学的交融点。"})
|
| 65 |
+
yield history, gr.MultimodalTextbox(value=None, interactive=True)
|
| 66 |
+
|
| 67 |
+
# --- 2026 赛博雅韵 UI 构建区 ---
|
| 68 |
+
shensist_theme = gr.themes.Base(
|
| 69 |
+
primary_hue=gr.themes.colors.indigo,
|
| 70 |
+
secondary_hue=gr.themes.colors.cyan,
|
| 71 |
+
neutral_hue=gr.themes.colors.slate,
|
| 72 |
+
font=["HarmonyOS Sans", "Roboto", "ui-sans-serif", "system-ui"],
|
| 73 |
+
).set(
|
| 74 |
+
body_background_fill="*neutral_950",
|
| 75 |
+
block_background_fill="*neutral_900",
|
| 76 |
+
block_border_width="1px",
|
| 77 |
+
block_border_color="*primary_800",
|
| 78 |
+
# 已彻底移除报错的 chatbot_code_background_color 参数
|
| 79 |
+
button_primary_background_fill="linear-gradient(90deg, *primary_700, *secondary_600)",
|
| 80 |
+
button_primary_text_color="white",
|
| 81 |
+
button_primary_border_color="transparent",
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
with gr.Blocks(theme=shensist_theme, title="神思庭 | SHENSIST NUCLEUS") as demo:
|
| 85 |
+
with gr.Row(elem_classes="header-bar"):
|
| 86 |
+
gr.Markdown(
|
| 87 |
+
"""
|
| 88 |
+
# 🏛️ **神思庭 · 数字灵愿枢纽** | SHENSIST AI NUCLEUS
|
| 89 |
+
> *连接神话造物与数字生命的声学界面*
|
| 90 |
+
"""
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
chatbot = gr.Chatbot(
|
| 94 |
+
label="超个体交互场域",
|
| 95 |
+
height=550,
|
| 96 |
+
show_copy_button=True,
|
| 97 |
+
bubble_full_width=False,
|
| 98 |
+
render_markdown=True
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
with gr.Row():
|
| 102 |
+
chat_input = gr.MultimodalTextbox(
|
| 103 |
+
interactive=True,
|
| 104 |
+
file_types=["audio"],
|
| 105 |
+
placeholder="输入指令 (如: '唱一下晴天'),或上传声纹样本...",
|
| 106 |
+
show_label=False,
|
| 107 |
+
scale=4,
|
| 108 |
+
container=True
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
chat_input.submit(shensist_chat, [chat_input, chatbot], [chatbot, chat_input])
|
| 112 |
+
|
| 113 |
+
if __name__ == "__main__":
|
| 114 |
+
temp_dir = os.path.abspath("./agent_cache")
|
| 115 |
+
demo.queue()
|
| 116 |
+
demo.launch(
|
| 117 |
+
server_name="0.0.0.0",
|
| 118 |
+
server_port=7860,
|
| 119 |
+
allowed_paths=[temp_dir]
|
| 120 |
+
)
|
packages.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
ffmpeg
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
yt-dlp
|
| 3 |
+
audio-separator[gpu]
|
| 4 |
+
onnxruntime-gpu
|