feat: v2 파이프라인 — 매일 2곡 다양한 장르 BGM 자동 생성/업로드

- daily_precache.py: Claude Code CLI 프리캐시 (날짜/계절/기념일 테마)
- daily_scheduler.py: ACE-Step 음악 → FLUX 이미지 → 영상 렌더 → 큐
- upload_scheduled.py: auto_shorts 동일 큐 방식 업로드
- PRECACHE_GUIDE_MUSIC.md: 19개 장르, 감성 제목, 재생목록 자유 생성
- generate_image.py: --lowvram 제거, GPU VRAM 확인 추가
- config.py: @animily-music 토큰 경로 변경

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
javamon
2026-05-25 19:24:50 +09:00
parent 37d13be48d
commit c3f8d6b288
8 changed files with 1688 additions and 22 deletions

View File

@@ -24,22 +24,40 @@ def _start_comfyui():
except Exception:
pass
# 기존 8188 (WAN) 종료
try:
requests.get("http://localhost:8188", timeout=2)
result = subprocess.run(["fuser", "8188/tcp"], capture_output=True, text=True)
for p in result.stdout.strip().split():
if p.strip().isdigit():
os.kill(int(p.strip()), signal.SIGTERM)
time.sleep(5)
except Exception:
pass
# GPU 프로세스 전부 종료 (ACE-Step, WAN, TTS)
for port in ["8188", "8001", "8000"]:
try:
result = subprocess.run(["fuser", f"{port}/tcp"], capture_output=True, text=True)
for p in result.stdout.strip().split():
if p.strip().isdigit():
os.kill(int(p.strip()), signal.SIGKILL)
except Exception:
pass
# TTS systemd 서비스 종료
subprocess.run(["sudo", "systemctl", "stop", "qwen-tts.service"], capture_output=True, timeout=10)
subprocess.run(["sudo", "systemctl", "disable", "qwen-tts.service"], capture_output=True, timeout=5)
# drop_caches + GPU VRAM 해제 대기
subprocess.run(["sudo", "sh", "-c", "echo 3 > /proc/sys/vm/drop_caches"], capture_output=True, timeout=5)
time.sleep(5)
# GPU에서 비관련 프로세스만 남을 때까지 대기 (최대 60초)
for _w in range(30):
try:
_gpu = subprocess.run(["nvidia-smi", "--query-compute-apps=pid,process_name", "--format=csv,noheader"],
capture_output=True, text=True, timeout=5)
_procs = [l for l in _gpu.stdout.strip().split("\n") if l.strip()]
_blocking = [p for p in _procs if any(x in p for x in ["ComfyUI", "Qwen3", "acestep", "ACE"])]
if not _blocking:
print(f" [FLUX] GPU 메모리 해제 확인 ({(_w+1)*2}s)", flush=True)
break
except:
break
time.sleep(2)
# FLUX ComfyUI 시작
print(" [FLUX] ComfyUI 시작 중...", flush=True)
subprocess.Popen(
[f"{COMFYUI_DIR}/venv/bin/python3", "main.py",
"--listen", "0.0.0.0", "--port", "8189", "--bf16-vae", "--lowvram"],
"--listen", "0.0.0.0", "--port", "8189", "--bf16-vae", "--disable-mmap"],
cwd=COMFYUI_DIR,
stdout=open("/tmp/comfyui_flux_music.log", "a"),
stderr=open("/tmp/comfyui_flux_music.log", "a"),
@@ -105,7 +123,7 @@ def generate_image(prompt, output_path):
}},
"4": {"class_type": "CLIPTextEncode", "inputs": {"clip": ["3", 0], "text": prompt}},
"5": {"class_type": "EmptyLatentImage", "inputs": {
"width": 1024, "height": 576, "batch_size": 1,
"width": 1344, "height": 768, "batch_size": 1,
}},
"6": {"class_type": "KSampler", "inputs": {
"model": ["2", 0], "positive": ["4", 0], "negative": ["4", 0],
@@ -134,9 +152,22 @@ def generate_image(prompt, output_path):
pid = resp.json().get("prompt_id")
# 완료 대기 (최대 15분)
while (time.time() - t0) < 900:
h = requests.get(f"{COMFYUI_URL}/history/{pid}", timeout=5).json()
# 완료 대기 (최대 20분, 프로세스 생존 확인)
_fail_count = 0
while (time.time() - t0) < 1200:
try:
h = requests.get(f"{COMFYUI_URL}/history/{pid}", timeout=30).json()
_fail_count = 0
except Exception:
_fail_count += 1
_alive = subprocess.run(["pgrep", "-f", "main.py.*8189"], capture_output=True).returncode == 0
if not _alive:
print(" [FLUX] 프로세스 죽음 (OOM 가능성)", flush=True)
return False
if _fail_count % 6 == 0:
print(f" [FLUX] HTTP 미응답 ({_fail_count}회) — 모델 로딩 대기...", flush=True)
time.sleep(10)
continue
if pid in h:
status = h[pid].get("status", {}).get("status_str", "")
if status == "success":
@@ -154,7 +185,7 @@ def generate_image(prompt, output_path):
return False
time.sleep(5)
print(f" [FLUX] 타임아웃 (15분)", flush=True)
print(f" [FLUX] 타임아웃 (20분)", flush=True)
return False
except Exception as e: