返回 AiToEarn
common.ts
1 import { z } from 'zod'
2
3 // ========== Volcengine Track Structure Schema (matches volcengine.interface.ts) ==========
4
5 const targetTimeSchema = z
6 .array(z.number())
7 .length(2)
8 .transform(value => value as [number, number])
9
10 // TransformFilter - 2D Transform
11 export const transformFilterSchema = z.object({
12 Type: z.literal('transform').describe('Filter type'),
13 PosX: z.number().describe('Element top-left X coordinate (pixels). Full-screen video MUST use 0, NOT canvas center!'),
14 PosY: z.number().describe('Element top-left Y coordinate (pixels). Full-screen video MUST use 0, NOT canvas center!'),
15 Width: z.number().describe('Element width (pixels)'),
16 Height: z.number().describe('Element height (pixels)'),
17 Rotation: z.number().optional().describe('Rotation angle [-360, 360], clockwise positive, rotates around element center'),
18 FlipX: z.boolean().optional().describe('Horizontal mirror flip'),
19 FlipY: z.boolean().optional().describe('Vertical mirror flip'),
20 Alpha: z.number().optional().describe('Opacity [0,1], 0 is transparent'),
21 })
22
23 // LutFilter - Color Filter
24 export const lutFilterSchema = z.object({
25 Type: z.literal('lut_filter').describe('Filter type'),
26 TargetTime: targetTimeSchema.describe('Filter time range in element [startMs, endMs]'),
27 Source: z.string().describe('Filter ID'),
28 Intensity: z.number().optional().describe('Filter intensity [0,1]'),
29 })
30
31 // EffectFilter - Visual Effect
32 export const effectFilterSchema = z.object({
33 Type: z.literal('effect_filter').describe('Filter type'),
34 TargetTime: targetTimeSchema.describe('Filter time range in element [startMs, endMs]'),
35 Source: z.string().describe('Effect ID'),
36 })
37
38 // TransitionFilter - Transition
39 export const transitionFilterSchema = z.object({
40 Type: z.literal('transition').describe('Filter type'),
41 Source: z.string().describe('Transition ID'),
42 Duration: z.number().describe('Transition duration (milliseconds)'),
43 })
44
45 // CropFilter - Area Crop
46 export const cropFilterSchema = z.object({
47 Type: z.literal('crop').describe('Filter type'),
48 PosX: z.number().describe('Crop area top-left X coordinate (pixels), NOT center point'),
49 PosY: z.number().describe('Crop area top-left Y coordinate (pixels), NOT center point'),
50 Width: z.number().describe('Crop area width (pixels)'),
51 Height: z.number().describe('Crop area height (pixels)'),
52 })
53
54 // TrimFilter - Time Trim
55 export const trimFilterSchema = z.object({
56 Type: z.literal('trim').describe('Filter type'),
57 StartTime: z.number().describe('Trim start time (milliseconds)'),
58 EndTime: z.number().describe('Trim end time (milliseconds)'),
59 })
60
61 // SpeedFilter - Playback Speed
62 export const speedFilterSchema = z.object({
63 Type: z.literal('speed').describe('Filter type'),
64 Speed: z.number().describe('Playback speed [0.1, 4]'),
65 })
66
67 // VideoAnimationsFilter - Video Animation
68 export const videoAnimationsFilterSchema = z.object({
69 Type: z.literal('video_animation').describe('Filter type'),
70 AnimRes: z.string().describe('Video animation ID'),
71 AnimStartTime: z.number().describe('Animation start time (milliseconds)'),
72 AnimEndTime: z.number().describe('Animation end time (milliseconds)'),
73 AnimLoop: z.boolean().optional().describe('Whether to loop'),
74 AnimLoopDuration: z.number().optional().describe('Loop animation duration (milliseconds)'),
75 })
76
77 // TextAnimationsFilter - Text Animation
78 export const textAnimationsFilterSchema = z.object({
79 Type: z.literal('text_animation').describe('Filter type'),
80 AnimInRes: z.string().optional().describe('Enter animation ID'),
81 AnimInDuration: z.number().optional().describe('Enter animation duration (milliseconds)'),
82 AnimOutRes: z.string().optional().describe('Exit animation ID'),
83 AnimOutDuration: z.number().optional().describe('Exit animation duration (milliseconds)'),
84 AnimLoopRes: z.string().optional().describe('Loop animation ID'),
85 AnimLoopDuration: z.number().optional().describe('Loop animation duration (milliseconds)'),
86 })
87
88 // AudioFadeFilter - Audio Fade
89 export const audioFadeFilterSchema = z.object({
90 Type: z.literal('a_fade').describe('Filter type'),
91 FadeIn: z.number().optional().describe('Fade in time (milliseconds)'),
92 FadeOut: z.number().optional().describe('Fade out time (milliseconds)'),
93 })
94
95 // AudioVolumeFilter - Volume Control
96 export const audioVolumeFilterSchema = z.object({
97 Type: z.literal('a_volume').describe('Filter type'),
98 Volume: z.number().describe('Volume, 0 is mute, 1 is default'),
99 })
100
101 // EqFilter - Image Equalizer
102 export const eqFilterSchema = z.object({
103 Type: z.literal('equalizer').describe('Filter type'),
104 TargetTime: targetTimeSchema.describe('Filter time range in element [startMs, endMs]'),
105 Brightness: z.number().optional().describe('Brightness [0, 1]'),
106 Saturation: z.number().optional().describe('Saturation [0, 1]'),
107 Tone: z.number().optional().describe('Tone [0, 1]'),
108 })
109
110 // DelogoFilter - Local Blur
111 export const delogoFilterSchema = z.object({
112 Type: z.literal('delogo').describe('Filter type'),
113 TargetTime: targetTimeSchema.describe('Filter time range in element [startMs, endMs]'),
114 DelogoType: z.string().optional().describe('Delogo type, default gaussian'),
115 PosX: z.number().describe('Local blur area top-left X coordinate (pixels), NOT center point'),
116 PosY: z.number().describe('Local blur area top-left Y coordinate (pixels), NOT center point'),
117 Width: z.number().describe('Local blur area width (pixels)'),
118 Height: z.number().describe('Local blur area height (pixels)'),
119 Sigma: z.number().optional().describe('Blur intensity [10,70]'),
120 Radius: z.number().optional().describe('Blur radius [10,70]'),
121 })
122
123 // GaussianFilter - Gaussian Blur
124 export const gaussianFilterSchema = z.object({
125 Type: z.literal('gaussian').describe('Filter type'),
126 TargetTime: targetTimeSchema.describe('Filter time range in element [startMs, endMs]'),
127 Radius: z.number().describe('Gaussian blur radius [10,70]'),
128 Sigma: z.number().describe('Gaussian blur intensity [10,70]'),
129 })
130
131 // Filter Union Schema
132 export const filterSchema = z.union([
133 transformFilterSchema,
134 lutFilterSchema,
135 effectFilterSchema,
136 transitionFilterSchema,
137 cropFilterSchema,
138 trimFilterSchema,
139 speedFilterSchema,
140 videoAnimationsFilterSchema,
141 textAnimationsFilterSchema,
142 audioFadeFilterSchema,
143 audioVolumeFilterSchema,
144 eqFilterSchema,
145 delogoFilterSchema,
146 gaussianFilterSchema,
147 ]).describe('Filter effect')
148
149 // TrackElement Schema
150 export const trackElementSchema = z.object({
151 Type: z.enum(['video', 'audio', 'image', 'text', 'subtitle', 'effect', 'gaussian', 'text_roll']).describe('Element type'),
152 Source: z.string().optional().describe('Resource source: vid://xxx, mid://xxx, tos://xxx or URL'),
153 TargetTime: targetTimeSchema.describe('Track time range [startMs, endMs], in milliseconds'),
154 // text/subtitle specific fields
155 Text: z.string().optional().describe('Text content'),
156 TextRes: z.string().optional().describe('Fancy text ID'),
157 FontType: z.string().optional().describe('Font ID'),
158 FontSize: z.number().optional().describe('Font size (pixels)'),
159 FontColor: z.string().optional().describe('Font color (RGBA)'),
160 BackgroundColor: z.string().optional().describe('Font background color (RGBA)'),
161 BorderColor: z.string().optional().describe('Font border color (RGBA)'),
162 BorderWidth: z.number().optional().describe('Font border width'),
163 LineMaxWidth: z.number().optional().describe('Auto line wrap width [-1, 1]'),
164 Typesetting: z.number().optional().describe('Text direction: 0=horizontal, 1=vertical'),
165 AlignType: z.number().optional().describe('Text alignment'),
166 // Extra - Filter list
167 Extra: z.array(filterSchema).optional().describe('Extra effects list (Filters)'),
168 }).describe('Track element')
169
170 // Canvas Schema
171 export const canvasSchema = z.object({
172 Width: z.number().describe('Canvas width (pixels)'),
173 Height: z.number().describe('Canvas height (pixels)'),
174 BackgroundColor: z.string().optional().describe('Canvas background color (RGBA)'),
175 })
176
177 // Codec Schema
178 export const codecSchema = z.object({
179 VideoCodec: z.string().optional().describe('Video codec: h264, h265, vp9'),
180 AudioCodec: z.string().optional().describe('Audio codec: aac'),
181 VideoBitRate: z.number().optional().describe('Video bitrate (bps)'),
182 AudioBitrate: z.number().optional().describe('Audio bitrate (kbps)'),
183 Crf: z.number().optional().describe('Constant quality factor [0,51]'),
184 Preset: z.string().optional().describe('Encoding speed preset'),
185 })
186
187 // Output Schema
188 export const outputSchema = z.object({
189 Fps: z.number().optional().describe('Output frame rate'),
190 DisableVideo: z.boolean().optional().describe('Output audio only'),
191 DisableAudio: z.boolean().optional().describe('Output video only'),
192 Alpha: z.boolean().optional().describe('Include Alpha channel'),
193 Codec: codecSchema.optional().describe('Codec settings'),
194 })
195
196 // submitDirectEditTask Schema
197 export const submitDirectEditTaskSchema = z.object({
198 Canvas: canvasSchema.optional().describe('Canvas configuration (optional — auto-detected from primary video source if omitted)'),
199 Output: outputSchema.optional().describe('Output configuration'),
200 Track: z.array(z.array(trackElementSchema)).describe('Track array, outer array is render layer (higher index = higher layer), inner array is elements on same track'),
201 })
202
203 export const getVideoEditTaskStatusSchema = z.object({
204 taskId: z.string().describe('Task ID (returned by submitDirectEditTask)'),
205 })
206
207 export enum VideoEditToolName {
208 SubmitDirectEditTask = 'submitDirectEditTask',
209 GetVideoEditTaskStatus = 'getVideoEditTaskStatus',
210 }
211
211 lines TYPESCRIPT