MUSIC-lab generate 요청 후 대기 시간 추가
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import time
|
||||
import uuid
|
||||
import requests
|
||||
from typing import List, Optional
|
||||
@@ -51,40 +52,57 @@ def _run_generation(task_id: str, params: dict) -> None:
|
||||
|
||||
update_task(task_id, "processing", 30, "음악 생성 중... (수 분 소요될 수 있습니다)")
|
||||
|
||||
# 1단계: 생성 요청 → ai_task_id 반환
|
||||
resp = requests.post(
|
||||
f"{MUSIC_AI_SERVER_URL}/generate",
|
||||
json=params,
|
||||
timeout=600, # 10분
|
||||
stream=True,
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
if resp.status_code != 200:
|
||||
update_task(task_id, "failed", 0, "", error=f"AI 서버 오류: {resp.status_code} {resp.text[:200]}")
|
||||
return
|
||||
|
||||
ai_task_id = resp.json().get("task_id")
|
||||
if not ai_task_id:
|
||||
update_task(task_id, "failed", 0, "", error="AI 서버 응답에 task_id가 없습니다")
|
||||
return
|
||||
|
||||
# 2단계: 상태 폴링 (최대 10분, 5초 간격) — AI 서버 progress/message 그대로 반영
|
||||
remote_url = None
|
||||
for _ in range(120):
|
||||
time.sleep(5)
|
||||
status_resp = requests.get(f"{MUSIC_AI_SERVER_URL}/status/{ai_task_id}", timeout=10)
|
||||
status_data = status_resp.json()
|
||||
ai_status = status_data.get("status")
|
||||
|
||||
# AI 서버의 progress/message를 로컬 task에 전달 (30~79 범위로 스케일)
|
||||
ai_progress = status_data.get("progress", 0)
|
||||
ai_message = status_data.get("message", "음악 생성 중...")
|
||||
scaled = 30 + int(ai_progress * 0.49) # 30% ~ 79%
|
||||
update_task(task_id, "processing", scaled, ai_message)
|
||||
|
||||
if ai_status == "succeeded":
|
||||
remote_url = status_data.get("audio_url")
|
||||
break
|
||||
elif ai_status == "failed":
|
||||
update_task(task_id, "failed", 0, "", error=status_data.get("error", "AI 서버 생성 실패"))
|
||||
return
|
||||
|
||||
if not remote_url:
|
||||
update_task(task_id, "failed", 0, "", error="AI 서버 타임아웃 (10분 초과)")
|
||||
return
|
||||
|
||||
update_task(task_id, "processing", 80, "파일 저장 중...")
|
||||
|
||||
# AI 서버 응답: binary audio 또는 JSON {"audio_url": "..."}
|
||||
content_type = resp.headers.get("content-type", "")
|
||||
filename = f"{task_id}.mp3"
|
||||
file_path = os.path.join(MUSIC_DATA_DIR, filename)
|
||||
|
||||
if "application/json" in content_type:
|
||||
result = resp.json()
|
||||
remote_url = result.get("audio_url") or result.get("url")
|
||||
if not remote_url:
|
||||
update_task(task_id, "failed", 0, "", error="AI 서버 응답에 audio_url이 없습니다")
|
||||
return
|
||||
# 원격 URL에서 파일 다운로드
|
||||
# 3단계: 오디오 파일 다운로드
|
||||
dl = requests.get(remote_url, timeout=120, stream=True)
|
||||
with open(file_path, "wb") as f:
|
||||
for chunk in dl.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
else:
|
||||
# binary audio 직접 저장
|
||||
with open(file_path, "wb") as f:
|
||||
for chunk in resp.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
# audio_url은 항상 Nginx 상대경로 (Mixed Content 방지)
|
||||
audio_url = f"/media/music/{filename}"
|
||||
|
||||
Reference in New Issue
Block a user