Add /api/mc/tts and /api/mc/voices endpoints, fix login to only show own voices
This commit is contained in:
+76
-3
@@ -590,7 +590,7 @@ def _resolve_guild_id() -> str:
|
||||
|
||||
@app.route("/api/mc/login", methods=["POST"])
|
||||
def api_mc_login():
|
||||
"""Minecraft mod login endpoint. Accepts JSON {"token": "..."} and returns user info + voices."""
|
||||
"""Minecraft mod login endpoint. Accepts JSON {"token": "..."} and returns user info + personal voices."""
|
||||
data = request.get_json(force=True) if request.is_json else {}
|
||||
token = data.get("token", "").strip()
|
||||
if not token:
|
||||
@@ -603,10 +603,11 @@ def api_mc_login():
|
||||
user_id = entry["user_id"]
|
||||
ucfg = get_user_config(user_id)
|
||||
voices = ucfg.get("chatterbox_voices", [])
|
||||
# Only return voices that belong to this user (prefixed with their user_id)
|
||||
result = []
|
||||
for v in voices:
|
||||
parts = v.split("_", 1)
|
||||
display = parts[1].rsplit(".", 1)[0] if len(parts) > 1 else v.rsplit(".", 1)[0]
|
||||
if v.startswith(f"{user_id}_"):
|
||||
display = v.split("_", 1)[1].rsplit(".", 1)[0]
|
||||
result.append({"filename": v, "display": display})
|
||||
|
||||
return jsonify({
|
||||
@@ -616,6 +617,78 @@ def api_mc_login():
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/mc/voices", methods=["GET"])
|
||||
def api_mc_voices():
|
||||
"""List all predefined voices from the Chatterbox server."""
|
||||
try:
|
||||
chatterbox_url = get_chatterbox_url()
|
||||
r = requests.get(f"{chatterbox_url}/get_predefined_voices", timeout=10)
|
||||
r.raise_for_status()
|
||||
return jsonify(r.json())
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 502
|
||||
|
||||
|
||||
@app.route("/api/mc/tts", methods=["POST"])
|
||||
def api_mc_tts():
|
||||
"""Generate TTS audio. Returns WAV bytes.
|
||||
JSON body: {"text": "...", "mode": "chatterbox|dectalk|morshu", "voice": "Emily.wav"}
|
||||
"""
|
||||
data = request.get_json(force=True) if request.is_json else {}
|
||||
text = (data.get("text") or "").strip()
|
||||
if not text:
|
||||
return jsonify({"error": "Missing text"}), 400
|
||||
|
||||
mode = data.get("mode", "chatterbox")
|
||||
voice = data.get("voice", "Emily.wav")
|
||||
|
||||
try:
|
||||
if mode == "chatterbox":
|
||||
chatterbox_url = get_chatterbox_url()
|
||||
payload = {
|
||||
"text": text,
|
||||
"voice_mode": "predefined",
|
||||
"predefined_voice_id": voice,
|
||||
"output_format": "wav",
|
||||
"split_text": False,
|
||||
}
|
||||
r = requests.post(f"{chatterbox_url}/tts", json=payload, timeout=120)
|
||||
r.raise_for_status()
|
||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||
|
||||
elif mode == "clone":
|
||||
chatterbox_url = get_chatterbox_url()
|
||||
payload = {
|
||||
"text": text,
|
||||
"voice_mode": "clone",
|
||||
"reference_audio_filename": voice,
|
||||
"output_format": "wav",
|
||||
"split_text": False,
|
||||
}
|
||||
r = requests.post(f"{chatterbox_url}/tts", json=payload, timeout=120)
|
||||
r.raise_for_status()
|
||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||
|
||||
elif mode == "dectalk":
|
||||
dectalk_url = get_dectalk_url()
|
||||
r = requests.get(f"{dectalk_url}/say", params={"text": text}, timeout=30)
|
||||
r.raise_for_status()
|
||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||
|
||||
elif mode == "morshu":
|
||||
r = requests.get("http://127.0.0.1:3002/say", params={"text": text}, timeout=60)
|
||||
r.raise_for_status()
|
||||
return r.content, 200, {"Content-Type": "audio/wav"}
|
||||
|
||||
else:
|
||||
return jsonify({"error": f"Unknown mode: {mode}"}), 400
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
return jsonify({"error": f"{mode} server not reachable"}), 502
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Routes — Chatterbox voice management
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user