diff --git a/capcut_agent/pipeline.py b/capcut_agent/pipeline.py index 395193e..bda5dbc 100644 --- a/capcut_agent/pipeline.py +++ b/capcut_agent/pipeline.py @@ -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, }}