1use std::collections::BTreeMap;
8
9use bytes::Bytes;
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
15pub enum VideoAspectRatio {
16 #[serde(rename = "16:9")]
18 R16x9,
19 #[serde(rename = "9:16")]
21 R9x16,
22 #[serde(rename = "1:1")]
24 R1x1,
25 #[serde(rename = "4:3")]
27 R4x3,
28 #[serde(rename = "3:4")]
30 R3x4,
31 #[serde(rename = "21:9")]
33 R21x9,
34 #[serde(rename = "9:21")]
36 R9x21,
37}
38
39#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
41pub enum VideoResolution {
42 #[serde(rename = "480p")]
44 P480,
45 #[serde(rename = "720p")]
47 P720,
48 #[serde(rename = "1080p")]
50 P1080,
51 #[serde(rename = "1K")]
53 K1,
54 #[serde(rename = "2K")]
56 K2,
57 #[serde(rename = "4K")]
59 K4,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "snake_case")]
65pub enum VideoFrameType {
66 FirstFrame,
68 LastFrame,
70}
71
72#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
76#[serde(rename_all = "snake_case")]
77pub enum VideoStatus {
78 #[default]
80 Pending,
81 InProgress,
83 Completed,
85 Failed,
87 Cancelled,
89 Expired,
91}
92
93impl VideoStatus {
94 pub fn is_terminal(self) -> bool {
96 matches!(
97 self,
98 VideoStatus::Completed
99 | VideoStatus::Failed
100 | VideoStatus::Cancelled
101 | VideoStatus::Expired
102 )
103 }
104}
105
106#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
108pub struct VideoImageUrl {
109 pub url: String,
111}
112
113#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
115pub struct VideoContentPartImage {
116 pub image_url: VideoImageUrl,
118 #[serde(rename = "type")]
120 pub kind: String,
121}
122
123impl VideoContentPartImage {
124 pub fn new(url: impl Into<String>) -> Self {
126 Self {
127 image_url: VideoImageUrl { url: url.into() },
128 kind: "image_url".into(),
129 }
130 }
131}
132
133#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
135pub struct VideoFrameImage {
136 pub image_url: VideoImageUrl,
138 #[serde(rename = "type")]
140 pub kind: String,
141 pub frame_type: VideoFrameType,
143}
144
145impl VideoFrameImage {
146 pub fn new(url: impl Into<String>, frame_type: VideoFrameType) -> Self {
148 Self {
149 image_url: VideoImageUrl { url: url.into() },
150 kind: "image_url".into(),
151 frame_type,
152 }
153 }
154}
155
156#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
158pub struct VideoProvider {
159 #[serde(skip_serializing_if = "Option::is_none", default)]
162 pub options: Option<BTreeMap<String, BTreeMap<String, Value>>>,
163}
164
165#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
167pub struct VideoGenerationRequest {
168 pub model: String,
170 pub prompt: String,
172 #[serde(skip_serializing_if = "Option::is_none", default)]
174 pub aspect_ratio: Option<VideoAspectRatio>,
175 #[serde(skip_serializing_if = "Option::is_none", default)]
177 pub callback_url: Option<String>,
178 #[serde(skip_serializing_if = "Option::is_none", default)]
180 pub duration: Option<u32>,
181 #[serde(skip_serializing_if = "Vec::is_empty", default)]
183 pub frame_images: Vec<VideoFrameImage>,
184 #[serde(skip_serializing_if = "Option::is_none", default)]
186 pub generate_audio: Option<bool>,
187 #[serde(skip_serializing_if = "Vec::is_empty", default)]
189 pub input_references: Vec<VideoContentPartImage>,
190 #[serde(skip_serializing_if = "Option::is_none", default)]
192 pub provider: Option<VideoProvider>,
193 #[serde(skip_serializing_if = "Option::is_none", default)]
195 pub resolution: Option<VideoResolution>,
196 #[serde(skip_serializing_if = "Option::is_none", default)]
198 pub seed: Option<i64>,
199 #[serde(skip_serializing_if = "Option::is_none", default)]
201 pub size: Option<String>,
202}
203
204#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
206pub struct VideoGenerationUsage {
207 #[serde(default)]
209 pub cost: Option<f64>,
210 #[serde(default)]
212 pub is_byok: bool,
213}
214
215#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
217pub struct VideoGenerationResponse {
218 #[serde(default)]
220 pub id: String,
221 #[serde(default)]
223 pub polling_url: String,
224 pub status: VideoStatus,
226 #[serde(default)]
228 pub error: String,
229 #[serde(default)]
231 pub generation_id: String,
232 #[serde(default)]
234 pub unsigned_urls: Vec<String>,
235 #[serde(default)]
237 pub usage: Option<VideoGenerationUsage>,
238}
239
240#[derive(Clone, Debug)]
243pub struct VideoContentResponse {
244 pub content: Bytes,
246 pub content_type: Option<String>,
248}
249
250#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
252pub struct VideoModel {
253 #[serde(default)]
255 pub id: String,
256 #[serde(default)]
258 pub name: String,
259 #[serde(default)]
261 pub canonical_slug: String,
262 #[serde(default)]
264 pub created: i64,
265 #[serde(default)]
267 pub description: String,
268 #[serde(default)]
270 pub hugging_face_id: Option<String>,
271 #[serde(default)]
273 pub allowed_passthrough_parameters: Vec<String>,
274 #[serde(default)]
276 pub generate_audio: Option<bool>,
277 #[serde(default)]
279 pub seed: Option<bool>,
280 #[serde(default)]
282 pub pricing_skus: BTreeMap<String, String>,
283 #[serde(default)]
285 pub supported_aspect_ratios: Vec<VideoAspectRatio>,
286 #[serde(default)]
288 pub supported_durations: Vec<u32>,
289 #[serde(default)]
291 pub supported_frame_images: Vec<VideoFrameType>,
292 #[serde(default)]
294 pub supported_resolutions: Vec<VideoResolution>,
295 #[serde(default)]
297 pub supported_sizes: Vec<String>,
298}
299
300#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
302pub struct VideoModelsResponse {
303 #[serde(default)]
305 pub data: Vec<VideoModel>,
306}