ai-chatbot/lib/video-canvas/media-contract.ts

23 lines
1.2 KiB
TypeScript

import { z } from "zod";
const fraction = z.number().finite().min(0).max(1);
export const videoTimeRangeSchema = z.object({ start: fraction, end: fraction })
.refine(range => range.end > range.start, "结束位置必须晚于开始位置");
export type VideoTimeRange = z.infer<typeof videoTimeRangeSchema>;
export const videoProcessSchema = z.discriminatedUnion("operation", [
z.object({ operation: z.literal("crop"), url: z.string().url(), rect: z.object({
x: fraction, y: fraction, width: fraction.positive(), height: fraction.positive(),
}).refine(rect => rect.x + rect.width <= 1.001 && rect.y + rect.height <= 1.001, "裁剪区域超出画面") }),
z.object({ operation: z.literal("audio-video"), url: z.string().url() }),
z.object({ operation: z.literal("trim"), url: z.string().url(), range: videoTimeRangeSchema }),
]);
export function toVideoTimeRange(range: VideoTimeRange, duration: number) {
if (!videoTimeRangeSchema.safeParse(range).success || !Number.isFinite(duration) || duration <= 0) throw new Error("剪辑范围无效");
const start = range.start * duration;
const end = range.end * duration;
if (end - start < 0.1) throw new Error("剪辑时长不能少于 0.1 秒");
return { start, end, duration: end - start };
}