Update app.py
Browse files
app.py
CHANGED
|
@@ -1,55 +1,61 @@
|
|
| 1 |
import json
|
| 2 |
import os
|
|
|
|
|
|
|
| 3 |
from google import genai
|
| 4 |
from google.genai import types
|
| 5 |
|
| 6 |
TAGS_FILE = "tags.json"
|
| 7 |
|
| 8 |
def load_tags():
|
| 9 |
-
"""讀取現有的標準標籤庫"""
|
| 10 |
if os.path.exists(TAGS_FILE):
|
| 11 |
with open(TAGS_FILE, "r", encoding="utf-8") as f:
|
| 12 |
return json.load(f)
|
| 13 |
-
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
def save_tags(tags_data):
|
| 17 |
-
"""將更新後的標籤庫寫回檔案"""
|
| 18 |
with open(TAGS_FILE, "w", encoding="utf-8") as f:
|
| 19 |
json.dump(tags_data, f, ensure_ascii=False, indent=2)
|
| 20 |
|
| 21 |
-
def
|
| 22 |
-
# 1. 讀取目前的動態標籤庫
|
| 23 |
current_tags = load_tags()
|
| 24 |
-
|
| 25 |
-
# 2. 初始化 Gemini Client (假設已設定好 API_KEY)
|
| 26 |
client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
|
| 27 |
|
| 28 |
-
#
|
| 29 |
prompt = f"""
|
| 30 |
你是一位專業的音樂與情感分析師。
|
| 31 |
-
請針對用戶提供的【歌曲:{song}】與【歌手:{artist}】,利用聯網搜尋功能找到這首歌的歌詞與
|
| 32 |
|
| 33 |
-
請
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
{json.dumps(current_tags, ensure_ascii=False)}
|
| 40 |
-
|
| 41 |
-
- 步驟 A(語意對齊):當你想到一個形容詞時,請先檢查它是否與【現有標籤庫】中的某個詞語意高度相似(例如:你想到了「悲傷」,而庫裡有「孤獨傷感」,你必須自動將其校正並採用「孤獨傷感」)。
|
| 42 |
-
- 步驟 B(發現新詞):如果你認為這首歌具備一個【現有標籤庫】完全無法涵蓋的全新概念(例如:歌風是賽博朋克或前衛電音),允許你創造新詞,但必須在該詞前面加上 `[NEW]` 標記(例如:`[NEW]電音迷幻`)。
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
2. 關鍵字生成:
|
| 47 |
-
- 【情緒基調】:[標籤, 標籤]
|
| 48 |
-
- 【視覺畫面】:[標籤, 標籤]
|
| 49 |
-
- 【適用場景】:[標籤, 標籤]
|
| 50 |
"""
|
| 51 |
|
| 52 |
-
# 4. 呼叫 Gemini 2.5 Flash
|
| 53 |
response = client.models.generate_content(
|
| 54 |
model='gemini-2.5-flash',
|
| 55 |
contents=prompt,
|
|
@@ -60,28 +66,21 @@ def analyze_song_v2(artist, song):
|
|
| 60 |
|
| 61 |
result_text = response.text
|
| 62 |
|
| 63 |
-
#
|
|
|
|
|
|
|
|
|
|
| 64 |
has_updates = False
|
| 65 |
-
for
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
for p in parts:
|
| 73 |
-
p = p.strip()
|
| 74 |
-
if "[NEW]" in p:
|
| 75 |
-
new_tag = p.replace("[NEW]", "").strip()
|
| 76 |
-
# 如果這個新詞不在庫裡,就加進去
|
| 77 |
-
if new_tag not in current_tags[category]:
|
| 78 |
-
current_tags[category].append(new_tag)
|
| 79 |
-
has_updates = True
|
| 80 |
-
|
| 81 |
-
# 6. 如果有新標籤加入,自動存檔,下次別首歌就能直接比對沿用!
|
| 82 |
if has_updates:
|
| 83 |
save_tags(current_tags)
|
| 84 |
|
| 85 |
-
#
|
| 86 |
-
clean_output =
|
| 87 |
return clean_output
|
|
|
|
| 1 |
import json
|
| 2 |
import os
|
| 3 |
+
import re
|
| 4 |
+
import gradio as gr
|
| 5 |
from google import genai
|
| 6 |
from google.genai import types
|
| 7 |
|
| 8 |
TAGS_FILE = "tags.json"
|
| 9 |
|
| 10 |
def load_tags():
|
|
|
|
| 11 |
if os.path.exists(TAGS_FILE):
|
| 12 |
with open(TAGS_FILE, "r", encoding="utf-8") as f:
|
| 13 |
return json.load(f)
|
| 14 |
+
return {
|
| 15 |
+
"情緒基調": ["溫柔療癒", "熱血激情"],
|
| 16 |
+
"視覺畫面": ["璀璨星空"],
|
| 17 |
+
"適用場景": ["深夜沉思"],
|
| 18 |
+
"風格曲風": ["華語流行"]
|
| 19 |
+
}
|
| 20 |
|
| 21 |
def save_tags(tags_data):
|
|
|
|
| 22 |
with open(TAGS_FILE, "w", encoding="utf-8") as f:
|
| 23 |
json.dump(tags_data, f, ensure_ascii=False, indent=2)
|
| 24 |
|
| 25 |
+
def analyze_song_v5(artist, song):
|
|
|
|
| 26 |
current_tags = load_tags()
|
|
|
|
|
|
|
| 27 |
client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
|
| 28 |
|
| 29 |
+
# 核心 Prompt:命令 AI 將所有客觀數據與四大類標籤全部融合成一條字串
|
| 30 |
prompt = f"""
|
| 31 |
你是一位專業的音樂與情感分析師。
|
| 32 |
+
請針對用戶提供的【歌曲:{song}】與【歌手:{artist}】,利用聯網搜尋功能找到這首歌的完整背景、歌詞與音樂資訊。
|
| 33 |
|
| 34 |
+
請嚴格按照以下格式輸出結果(包含兩個區塊):
|
| 35 |
+
|
| 36 |
+
### 📝 1. 意境與情境描述
|
| 37 |
+
[請用 150 字以內,精準、優美地簡述這首歌在描述什麼樣的情境、故事或情感。]
|
| 38 |
+
|
| 39 |
+
### 🏷️ 2. 統一標籤庫
|
| 40 |
+
[請將這首歌的所有相關標籤,全部統一用「英文逗號 ,」隔開,排成一整行輸出,不要分段。]
|
| 41 |
|
| 42 |
+
字串中必須包含以下兩大類標籤:
|
| 43 |
+
1. 靜態標籤(直接輸出,絕對不要加任何 [NEW] 標記):
|
| 44 |
+
專輯或歌曲衍生名、發行年份、年代標籤(如 2010年代, 2010s)、地區、相關影視作品名稱、最著名的副歌第一句歌詞、歌曲速度(如 118 BPM)。
|
| 45 |
+
|
| 46 |
+
2. 動態標籤(必須對照下方的【標準資料庫】進行語意對齊):
|
| 47 |
+
包含【情緒基調】、【視覺畫面】、【適用場景】、【風格曲風】。
|
| 48 |
+
- 語意對齊:如果你想到的詞與下方資料庫中的詞高度相似,必須自動校正並採用資料庫中的詞。
|
| 49 |
+
- 發現新詞規則:如果你認為現有資料庫無法涵蓋,允許你創造新詞,但必須在該詞前面加上 `[NEW:類別]` 標記。
|
| 50 |
+
(例如:創造新曲風寫成 `[NEW:風格曲風]林式情歌`;創造新情感寫成 `[NEW:情緒基調]狂放嘶吼`)。
|
| 51 |
+
|
| 52 |
+
【目前的標準資料庫】(供你對齊使用):
|
| 53 |
{json.dumps(current_tags, ensure_ascii=False)}
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
+
正確的【統一標籤庫】輸出範例(必須只有一行長字串):
|
| 56 |
+
因你而在, Stories Untold, 2013, 2010年代, 2010s, 台灣, Taiwan, 謝謝你引領我向前, 118 BPM, [NEW:風格曲風]林式情歌, 溫柔療癒, 璀璨星空, 深夜沉思
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
"""
|
| 58 |
|
|
|
|
| 59 |
response = client.models.generate_content(
|
| 60 |
model='gemini-2.5-flash',
|
| 61 |
contents=prompt,
|
|
|
|
| 66 |
|
| 67 |
result_text = response.text
|
| 68 |
|
| 69 |
+
# 後台核心技術:利用正則表達式,精準抓出帶有類別標籤的 [NEW:類別]新詞
|
| 70 |
+
# 這會抓出像 ('風格曲風', '林式情歌') 這樣的組合
|
| 71 |
+
new_found_tags = re.findall(r'\[NEW:(情緒基調|視覺畫面|適用場景|風格曲風)\]([^,\n]+)', result_text)
|
| 72 |
+
|
| 73 |
has_updates = False
|
| 74 |
+
for category, tag in new_found_tags:
|
| 75 |
+
tag = tag.strip()
|
| 76 |
+
# 確保這個新詞不在該類別的 JSON 清單中,然後塞進去
|
| 77 |
+
if tag not in current_tags[category]:
|
| 78 |
+
current_tags[category].append(tag)
|
| 79 |
+
has_updates = True
|
| 80 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
if has_updates:
|
| 82 |
save_tags(current_tags)
|
| 83 |
|
| 84 |
+
# 用正則把所有的 `[NEW:XXXXX]` 標記通通抹除乾淨,不留痕跡
|
| 85 |
+
clean_output = re.sub(r'\[NEW:[^\]]+\]', '', result_text)
|
| 86 |
return clean_output
|