use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::error::AiMuxError;
use crate::shared::{
AbortSignal, AspectRatio, SharedHeaders, SharedProviderMetadata, SharedProviderOptions, Size,
Warning,
};
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub enum VideoFile {
File {
media_type: String,
data: VideoFileData,
},
Url {
url: String,
media_type: Option<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub enum VideoFileData {
Base64(String),
Binary(Vec<u8>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)]
#[ts(export)]
pub enum VideoFrameType {
FirstFrame,
LastFrame,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct VideoFrameImage {
pub image: VideoFile,
pub frame_type: VideoFrameType,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub enum VideoData {
Url { url: String, media_type: String },
Base64 { data: String, media_type: String },
Binary { data: Vec<u8>, media_type: String },
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct VideoCallOptions {
pub prompt: Option<String>,
pub n: u32,
pub aspect_ratio: Option<AspectRatio>,
pub resolution: Option<Size>,
pub duration: Option<u32>,
pub fps: Option<u32>,
pub seed: Option<u64>,
pub image: Option<VideoFile>,
pub frame_images: Option<Vec<VideoFrameImage>>,
pub input_references: Option<Vec<VideoFile>>,
pub generate_audio: Option<bool>,
pub provider_options: SharedProviderOptions,
#[serde(skip)]
#[ts(skip)]
pub abort_signal: Option<AbortSignal>,
pub headers: Option<SharedHeaders>,
}
impl VideoCallOptions {
pub fn new(prompt: impl Into<String>) -> Self {
Self {
prompt: Some(prompt.into()),
n: 1,
aspect_ratio: None,
resolution: None,
duration: None,
fps: None,
seed: None,
image: None,
frame_images: None,
input_references: None,
generate_audio: None,
provider_options: SharedProviderOptions::new(),
abort_signal: None,
headers: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct VideoResult {
pub videos: Vec<VideoData>,
pub warnings: Vec<Warning>,
pub provider_metadata: Option<SharedProviderMetadata>,
pub response: VideoResponse,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
#[ts(export)]
pub struct VideoResponse {
pub timestamp: Option<String>,
pub model_id: Option<String>,
pub headers: Option<SharedHeaders>,
}
#[async_trait]
pub trait VideoModel: Send + Sync {
fn specification_version(&self) -> &'static str {
"v4"
}
fn provider(&self) -> &str;
fn model_id(&self) -> &str;
fn max_videos_per_call(&self) -> Option<u32>;
async fn do_generate(&self, options: &VideoCallOptions) -> Result<VideoResult, AiMuxError>;
}