export type ReframeAspectRatio = '9:16' | '1:1'; export type ReframeCropMode = 'fixed' | 'linear' | 'contain'; export type ReframeSubjectKind = 'person' | 'vehicle' | 'object' | 'group' | 'none'; export type ReframeHoldPolicy = 'forbid' | 'allow'; export type ReframeCaptionProfile = 'social-large' | 'social-standard'; export interface ReframeTarget { aspectRatio: ReframeAspectRatio; width: number; height: number; } export interface ReframeSubject { kind: ReframeSubjectKind; label: string; anchor?: { x: number; y: number; verified: boolean; endX?: number; endY?: number; width?: number; height?: number; }; } export interface ReframeFixedCrop { mode: 'fixed'; x: number; y: number; } export interface ReframeLinearCrop { mode: 'linear'; startX: number; endX: number; startY: number; endY: number; } export interface ReframeContainCrop { mode: 'contain'; } export type ReframeCrop = ReframeFixedCrop | ReframeLinearCrop | ReframeContainCrop; export interface ReframeShot { startSeconds: number; endSeconds: number; sourceStartSeconds?: number; sourceEndSeconds?: number; subject: ReframeSubject; crop: ReframeCrop; centerTolerancePercent: number; allowTightCrop: boolean; allowHold: boolean; holdSeconds?: number; note?: string; } export interface ReframeCaptionOptions { sourcePath?: string; profile: ReframeCaptionProfile; burnIn: boolean; allowBurnedCaptionSource: boolean; } export interface ReframePlan { schemaVersion: 1; sourcePath: string; target: ReframeTarget; defaultHoldPolicy: ReframeHoldPolicy; shots: ReframeShot[]; captions: ReframeCaptionOptions; } export interface ReframeSourceContext { sourceDurationSeconds: number; sourceWidth: number; sourceHeight: number; frameRate?: number; } export interface ReframeCropWindow { width: number; height: number; }