diff --git a/music-lab/app/pipeline/video.py b/music-lab/app/pipeline/video.py index d1ceb44..2fc6091 100644 --- a/music-lab/app/pipeline/video.py +++ b/music-lab/app/pipeline/video.py @@ -11,7 +11,15 @@ from . import storage logger = logging.getLogger("music-lab.video") ENCODER_URL = os.getenv("WINDOWS_VIDEO_ENCODER_URL", "") -ENCODER_TIMEOUT_S = 200 # Windows 서버 ffmpeg 180s + 마진 +ENCODER_TIMEOUT_BASE_S = 300 # 짧은 영상용 base + + +def _encoder_timeout(duration_sec: int) -> int: + """duration에 비례한 HTTP timeout — Windows ffmpeg timeout (~0.3x duration + 180)에 60s 마진 추가. + + 1분 → 300s, 30분 → 780s, 60분 → 1320s, 120분 → 2400s + """ + return max(ENCODER_TIMEOUT_BASE_S, int(duration_sec * 0.3) + 240) # NAS 호스트 절대경로 prefix — docker bind mount의 host 측 NAS_VIDEOS_ROOT = os.getenv("NAS_VIDEOS_ROOT", "/volume1/docker/webpage/data/videos") @@ -52,10 +60,11 @@ def generate(*, pipeline_id: int, audio_path: str, cover_path: str, "tracks": tracks or [], } - logger.info("Windows 인코더 호출: pipeline=%d audio=%s style=%s bg_mode=%s", - pipeline_id, audio_path, style, background_mode) + timeout_s = _encoder_timeout(duration_sec) + logger.info("Windows 인코더 호출 (timeout=%ds): pipeline=%d duration=%ds style=%s bg_mode=%s", + timeout_s, pipeline_id, duration_sec, style, background_mode) try: - with httpx.Client(timeout=ENCODER_TIMEOUT_S) as client: + with httpx.Client(timeout=timeout_s) as client: resp = client.post(f"{ENCODER_URL}/encode_video", json=payload) except (httpx.ConnectError, httpx.ReadTimeout, httpx.WriteTimeout, httpx.NetworkError) as e: raise VideoGenerationError(f"Windows 인코더 연결 실패: {e}")