컷별 자막 추출 헬퍼 함수 추가 (captions_for_places)

받아쓰기(ASR) 결과에서 컷 구간별로 자막을 이어붙이는 순수 함수.
- 시간축 겹침 판정: 닿기만(경계) 제외, 조금이라도 겹치면 포함
- 공백 정규화: 여러 칸 → 공백 하나
- 토큰 제한: cap 문자에서 자르기 (Gemini 효율)
- 테스트 모두 통과 (경계 규칙·공백·길이·엣지 케이스)

다음 단계(2단)에서 세 탭이 모두 호출할 예정.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-08-04 17:12:01 +09:00
parent a1f98b0b53
commit aab2a3199b

View File

@ -167,6 +167,21 @@ def _remap_placements(placements, keep_sorted):
for p0, p1 in placements] for p0, p1 in placements]
def captions_for_places(captions, places, *, cap: int = 500):
"""컷 구간마다 그 구간에 걸친 자막을 이어붙인다 — 댓글 추천의 근거.
`captions`·`places` **같은(압축) 타임라인** 좌표여야 한다. 겹치는 부분이
조금이라도 있으면 컷의 말로 본다(경계에 닿기만 하는 제외).
cap 자에서 자른다 이상은 Gemini 토큰만 먹고 매칭 정확도가 오른다.
Returns: places 같은 길이의 문자열 리스트
"""
out = []
for p0, p1 in places:
parts = [txt for cs, ce, txt in captions if cs < p1 and ce > p0 and txt]
out.append(" ".join(" ".join(parts).split())[:cap])
return out
def _safe_name(name: str) -> str: def _safe_name(name: str) -> str:
s = "".join(c for c in name if c.isalnum() or c in (" ", "_", "-", ".")).strip() s = "".join(c for c in name if c.isalnum() or c in (" ", "_", "-", ".")).strip()
return s[:60] or "video" return s[:60] or "video"