bg_analyze가 구간 위치를 ranges_sec/raw_places/places로 state에 담는다

구간 탭에서 댓글 카드를 컷 단위로 배치하려면 "구간 N이 압축 타임라인의
어디인지"를 알아야 한다. 지금까지는 유튜브 구간을 다운로드·병합만 하고
그 경계 정보를 버렸다. 원본 시각(ranges_sec), 병합본 누적 구간
(raw_places), 무음 제거 후 압축 타임라인 구간(places)을 state에 추가한다.
파일 탭은 세 키 모두 빈 리스트로 유지되어 동작이 바뀌지 않는다(회귀 검증 완료).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-08-05 10:28:30 +09:00
parent bfba87288f
commit 58fab2b2a4

View File

@ -12,7 +12,7 @@ from __future__ import annotations
import asyncio
import os
import time
from typing import AsyncIterator, Dict, List
from typing import AsyncIterator, Dict, List, Tuple
from typing import Optional
@ -227,9 +227,21 @@ async def bg_analyze(
t_all = time.perf_counter()
use_gemini = has_gemini_key()
# 구간 탭이 "구간 N이 타임라인의 어디인지" 알아야 자막·배치·장수를 컷 단위로 낼 수 있다.
# 파일 탭(유튜브 아님)은 빈 리스트 → 아무 데서도 안 쓰인다.
ranges_sec: List[Tuple[float, float]] = []
raw_places: List[Tuple[float, float]] = []
# ── 유튜브 여러 구간 다운로드 + 병합 (URL 입력 시) ──
if youtube:
ranges = youtube.get("ranges") or [(youtube.get("start", ""), youtube.get("end", ""))]
from .paste import parse_time
c = 0.0
for s, e in ranges:
ss, ee = parse_time(str(s)), parse_time(str(e))
ranges_sec.append((ss, ee))
raw_places.append((c, c + (ee - ss)))
c += ee - ss
yield {"type": "step", "id": "download", "status": "start"}
rng_txt = ", ".join(f"{s}~{e}" for s, e in ranges)
yield {"type": "log", "msg": f"유튜브 {len(ranges)}개 구간 다운로드·병합 중… [{rng_txt}]"}
@ -264,6 +276,8 @@ async def bg_analyze(
yield {"type": "error", "message": "오디오가 없거나 전부 무음입니다."}
return
kept = sum(e - s for s, e in keep)
# raw_places(병합본 좌표) → 압축 타임라인 좌표. 자막·배치·장수는 전부 이걸 쓴다.
places = _remap_placements(raw_places, keep) if raw_places else []
await _floor(t)
yield {"type": "step", "id": "silence", "status": "done",
"elapsed": round(time.perf_counter() - t, 1),
@ -307,6 +321,7 @@ async def bg_analyze(
"video_clips": video_clips, "captions": captions, "total": total,
"draft_name": draft_name, "title_top": title_top, "title_main": title_main,
"channel": channel, "t_all": t_all,
"ranges_sec": ranges_sec, "raw_places": raw_places, "places": places,
}}