40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
from dataclasses import dataclass
|
|
from typing import Literal
|
|
|
|
from PIL import Image
|
|
from pydantic import BaseModel
|
|
|
|
SceneKind = Literal["clip", "stills", "scroll", "poster"]
|
|
|
|
|
|
class Scene(BaseModel):
|
|
"""나레이션 큐 하나에 대응하는 화면."""
|
|
cue: int
|
|
kind: SceneKind
|
|
section: str | None = None # scroll 시작점이 된 섹션 이름
|
|
tag: str | None = None # 그 섹션의 태그. 왜 골랐는지 남긴다
|
|
# scroll은 조각이 아니라 롱이미지 위에서 일어난다. 아래 셋이 그 좌표다
|
|
source: str | None = None # 훑을 롱이미지 (detail_01 …)
|
|
y0: float | None = None # 시작 위치. 롱이미지 높이 대비 0~1
|
|
y1: float | None = None # 끝 위치
|
|
|
|
|
|
class LongcutPlan(BaseModel):
|
|
scenes: list[Scene]
|
|
|
|
|
|
class EndBandInfo(BaseModel):
|
|
"""엔드밴드 두 줄. 위가 공연명, 아래가 일시·장소."""
|
|
title: str
|
|
detail: str
|
|
|
|
|
|
@dataclass
|
|
class LongcutResult:
|
|
video: bytes
|
|
thumbnail: bytes # 첫 프레임. 0초가 포스터 원본이라 그대로 정지컷이 된다
|
|
duration: float
|
|
frames: int
|
|
plan: LongcutPlan
|
|
proof: Image.Image | None = None
|