|
|
|
@ -222,6 +222,14 @@ def generate_video(prompt): |
|
|
|
|
|
|
|
|
|
|
|
# Логируем структуру для диагностики |
|
|
|
# Логируем структуру для диагностики |
|
|
|
logger.info(f"📋 History keys: {list(history.keys())}") |
|
|
|
logger.info(f"📋 History keys: {list(history.keys())}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Проверяем статус выполнения — ComfyUI может сообщать об ошибках тут |
|
|
|
|
|
|
|
if "status" in history: |
|
|
|
|
|
|
|
status_info = history["status"] |
|
|
|
|
|
|
|
logger.info(f"📋 Execution status: {json.dumps(status_info)}") |
|
|
|
|
|
|
|
if status_info.get("status_str") == "error": |
|
|
|
|
|
|
|
logger.error(f"❌ ComfyUI execution error! Messages: {status_info.get('messages', [])}") |
|
|
|
|
|
|
|
|
|
|
|
if "outputs" in history: |
|
|
|
if "outputs" in history: |
|
|
|
logger.info(f"📋 Output nodes: {list(history['outputs'].keys())}") |
|
|
|
logger.info(f"📋 Output nodes: {list(history['outputs'].keys())}") |
|
|
|
for node_id, node_output in history["outputs"].items(): |
|
|
|
for node_id, node_output in history["outputs"].items(): |
|
|
|
@ -263,11 +271,17 @@ def generate_video(prompt): |
|
|
|
logger.error(f"❌ File not found: {video_path}") |
|
|
|
logger.error(f"❌ File not found: {video_path}") |
|
|
|
continue |
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_size = os.path.getsize(video_path) |
|
|
|
|
|
|
|
logger.info(f"📏 Video file size: {file_size} bytes ({file_size/1024:.1f} KB)") |
|
|
|
|
|
|
|
|
|
|
|
with open(video_path, "rb") as f: |
|
|
|
with open(video_path, "rb") as f: |
|
|
|
video_b64 = base64.b64encode(f.read()).decode("utf-8") |
|
|
|
video_b64 = base64.b64encode(f.read()).decode("utf-8") |
|
|
|
|
|
|
|
|
|
|
|
logger.info(f"✅ Video loaded: {len(video_b64)} chars base64") |
|
|
|
logger.info(f"✅ Video loaded: {len(video_b64)} chars base64") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if file_size < 50000: |
|
|
|
|
|
|
|
logger.warning(f"⚠️ Video suspiciously small ({file_size} bytes) — likely black/empty frames!") |
|
|
|
|
|
|
|
|
|
|
|
# Очистка |
|
|
|
# Очистка |
|
|
|
try: |
|
|
|
try: |
|
|
|
os.remove(video_path) |
|
|
|
os.remove(video_path) |
|
|
|
@ -516,6 +530,31 @@ def comfyui_status(): |
|
|
|
return jsonify(result) |
|
|
|
return jsonify(result) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/comfyui/logs", methods=["GET"]) |
|
|
|
|
|
|
|
def comfyui_logs(): |
|
|
|
|
|
|
|
"""Получить последние логи ComfyUI — без авторизации. ?lines=100""" |
|
|
|
|
|
|
|
lines = request.args.get("lines", "100") |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
result = subprocess.run( |
|
|
|
|
|
|
|
["journalctl", "-u", "comfyui", "-n", str(lines), "--no-pager"], |
|
|
|
|
|
|
|
capture_output=True, text=True, timeout=10 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
return jsonify({"logs": result.stdout, "stderr": result.stderr}) |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
return jsonify({"error": str(e)}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/comfyui/system_stats", methods=["GET"]) |
|
|
|
|
|
|
|
def comfyui_system_stats(): |
|
|
|
|
|
|
|
"""Проксирует system_stats из ComfyUI — без авторизации.""" |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
url = f"http://{COMFY_HOST}:{COMFY_PORT}/system_stats" |
|
|
|
|
|
|
|
with urllib.request.urlopen(url, timeout=5) as resp: |
|
|
|
|
|
|
|
return jsonify(json.loads(resp.read())) |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
return jsonify({"error": str(e)}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/run", methods=["POST"]) |
|
|
|
@app.route("/run", methods=["POST"]) |
|
|
|
def run_job(): |
|
|
|
def run_job(): |
|
|
|
"""Отправляет задачу в очередь. Возвращает job_id сразу.""" |
|
|
|
"""Отправляет задачу в очередь. Возвращает job_id сразу.""" |
|
|
|
|