diff --git a/crates/api_clients/fal_client/src/requests/webhook/video/enqueue_seedance_1_lite_image_to_video_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/video/enqueue_seedance_1_lite_image_to_video_webhook.rs index 996259cba6..22d070b6f1 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/video/enqueue_seedance_1_lite_image_to_video_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/video/enqueue_seedance_1_lite_image_to_video_webhook.rs @@ -57,6 +57,8 @@ pub async fn enqueue_seedance_1_lite_image_to_video_webhook { + pub image_url: U, + pub webhook_url: V, + pub prompt: &'a str, + pub api_key: &'a FalApiKey, + pub camera_fixed: bool, + pub duration: Seedance1ProDuration, + pub resolution: Seedance1ProResolution, + pub seed: Option, +} + +#[derive(Copy, Clone, Debug)] +pub enum Seedance1ProDuration { + FiveSeconds, + TenSeconds, + TwelveSeconds, +} + +#[derive(Copy, Clone, Debug)] +pub enum Seedance1ProResolution { + FourEightyP, // 480p + SevenTwentyP, // 720p + TenEightyP, // 1080p +} + +pub async fn enqueue_seedance_1_pro_image_to_video_webhook( + args: Seedance1ProArgs<'_, U, V> +) -> Result { + let duration = match args.duration { + Seedance1ProDuration::FiveSeconds => Some("5".to_string()), + Seedance1ProDuration::TenSeconds => Some("10".to_string()), + Seedance1ProDuration::TwelveSeconds => Some("12".to_string()), + }; + + let resolution = match args.resolution { + Seedance1ProResolution::FourEightyP => Some("480p".to_string()), + Seedance1ProResolution::SevenTwentyP => Some("720p".to_string()), + Seedance1ProResolution::TenEightyP => Some("1080p".to_string()), + }; + + let image_url = args.image_url.as_str().to_string(); + + let request = SeedanceImageToVideoProRequest { + image_url, + prompt: args.prompt.to_string(), + duration, + resolution, + // TODO: Add these later + camera_fixed: None, + // Static + enable_safety_checker: Some(false), + }; + + let result = seedance_v1_pro_image_to_video(request) + .with_api_key(&args.api_key.0) + .queue_webhook(args.webhook_url) + .await; + + result.map_err(|err| classify_fal_error(err)) +} + + +#[cfg(test)] +mod tests { + use crate::creds::fal_api_key::FalApiKey; + use crate::requests::webhook::video::enqueue_seedance_1_pro_image_to_video_webhook::{enqueue_seedance_1_pro_image_to_video_webhook, Seedance1ProArgs, Seedance1ProDuration, Seedance1ProResolution}; + use errors::AnyhowResult; + use std::fs::read_to_string; + use test_data::web::image_urls::TALL_MOCHI_WITH_GLASSES_IMAGE_URL; + + #[tokio::test] + #[ignore] + async fn test() -> AnyhowResult<()> { + // XXX: Don't commit secrets! + let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?; + + let api_key = FalApiKey::from_str(&secret); + + let args = Seedance1ProArgs { + image_url: TALL_MOCHI_WITH_GLASSES_IMAGE_URL, + prompt: "shiba in glasses runs to the lake and stands by the shore", + api_key: &api_key, + camera_fixed: false, + duration: Seedance1ProDuration::FiveSeconds, + resolution: Seedance1ProResolution::SevenTwentyP, + seed: None, + webhook_url: "https://example.com/webhook", + }; + + let result = enqueue_seedance_1_pro_image_to_video_webhook(args).await?; + + Ok(()) + } +} diff --git a/crates/api_clients/fal_client/src/requests/webhook/video/mod.rs b/crates/api_clients/fal_client/src/requests/webhook/video/mod.rs index 05de033c3e..94ba9a5fb0 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/video/mod.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/video/mod.rs @@ -2,6 +2,7 @@ pub mod enqueue_kling_16_pro_image_to_video_webhook; pub mod enqueue_kling_21_master_image_to_video_webhook; pub mod enqueue_kling_21_pro_image_to_video_webhook; pub mod enqueue_seedance_1_lite_image_to_video_webhook; +pub mod enqueue_seedance_1_pro_image_to_video_webhook; pub mod enqueue_veo_2_image_to_video_webhook; pub mod enqueue_veo_3_fast_image_to_video_webhook; pub mod enqueue_veo_3_image_to_video_webhook; \ No newline at end of file diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/lite/image_to_video/mod.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/lite/image_to_video/mod.rs index 06fc738325..4f44632979 100644 --- a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/lite/image_to_video/mod.rs +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/lite/image_to_video/mod.rs @@ -26,6 +26,9 @@ pub struct ImageToVideoRequest { pub prompt: String, pub seed: i32, + + #[serde(skip_serializing_if = "Option::is_none")] + pub enable_safety_checker: Option, } #[derive(Debug, Serialize, Deserialize, Default)] diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/mod.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/mod.rs index 6cbbc2be2a..c9b19f4f98 100644 --- a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/mod.rs +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/mod.rs @@ -11,4 +11,5 @@ feature = "endpoints_fal-ai_bytedance" ))) )] -pub mod lite; \ No newline at end of file +pub mod lite; +pub mod pro; \ No newline at end of file diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/image_to_video.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/image_to_video.rs new file mode 100644 index 0000000000..22d3aa8709 --- /dev/null +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/image_to_video.rs @@ -0,0 +1,62 @@ +#[allow(unused_imports)] +use crate::prelude::*; +#[allow(unused_imports)] +use serde::{Deserialize, Serialize}; +#[allow(unused_imports)] +use std::collections::HashMap; + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct SeedanceImageToVideoProRequest { + pub prompt: String, + + pub image_url: String, + + /// The resolution of the generated video frame + #[serde(skip_serializing_if = "Option::is_none")] + pub resolution: Option, + + /// The duration of the generated video in seconds + #[serde(skip_serializing_if = "Option::is_none")] + pub duration: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub camera_fixed: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub enable_safety_checker: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct I2VOutput { + /// The generated video + /// {"url":"https://v2.fal.media/files/36087878b0c1435bb75c19b64b7db178_output.mp4"} + pub video: File, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct File { + /// The URL where the file can be downloaded from. + pub url: String, + + // /// The mime type of the file. + // /// "image/png" + // #[serde(skip_serializing_if = "Option::is_none")] + // pub content_type: Option, + // /// File data + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_data: Option, + // /// The name of the file. It will be auto-generated if not provided. + // /// "z9RV14K95DvU.png" + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_name: Option, + // /// The size of the file in bytes. + // /// 4404019 + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_size: Option, +} + +pub fn seedance_v1_pro_image_to_video( + params: SeedanceImageToVideoProRequest, +) -> FalRequest { + FalRequest::new("fal-ai/bytedance/seedance/v1/pro/image-to-video", params) +} diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/mod.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/mod.rs new file mode 100644 index 0000000000..e2f49a5500 --- /dev/null +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/bytedance/seedance/v1/pro/mod.rs @@ -0,0 +1 @@ +pub mod image_to_video; \ No newline at end of file diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs new file mode 100644 index 0000000000..1ecf259fbd --- /dev/null +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/edit.rs @@ -0,0 +1,53 @@ +use crate::prelude::{Deserialize, FalRequest, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct Gemini25FlashImageEditInput { + pub prompt: String, + + pub image_urls: Vec, + + /// 1 - 4 + #[serde(skip_serializing_if = "Option::is_none")] + pub num_images: Option, + + /// "jpeg" or "png" + #[serde(skip_serializing_if = "Option::is_none")] + pub output_format: Option, + + /// Resolution, eg. "720p" + #[serde(skip_serializing_if = "Option::is_none")] + pub resolution: Option, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +pub struct File { + /// The URL where the file can be downloaded from. + pub url: String, + + // /// The mime type of the file. + // /// "image/png" + // #[serde(skip_serializing_if = "Option::is_none")] + // pub content_type: Option, + // /// File data + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_data: Option, + // /// The name of the file. It will be auto-generated if not provided. + // /// "z9RV14K95DvU.png" + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_name: Option, + // /// The size of the file in bytes. + // /// 4404019 + // #[serde(skip_serializing_if = "Option::is_none")] + // pub file_size: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Gemini25FlashImageEditOutput { + pub images: Vec, +} + +pub fn gemini_25_flash_image_edit( + params: Gemini25FlashImageEditInput, +) -> FalRequest { + FalRequest::new("fal-ai/gemini-25-flash-image/edit", params) +} diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/mod.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/mod.rs new file mode 100644 index 0000000000..0a4a4d0e41 --- /dev/null +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/gemini_25_flash_image/mod.rs @@ -0,0 +1 @@ +pub mod edit; \ No newline at end of file diff --git a/crates/vendor/fal-rs/src/endpoints/fal_ai/mod.rs b/crates/vendor/fal-rs/src/endpoints/fal_ai/mod.rs index 2403b0d6c0..1374972ee0 100644 --- a/crates/vendor/fal-rs/src/endpoints/fal_ai/mod.rs +++ b/crates/vendor/fal-rs/src/endpoints/fal_ai/mod.rs @@ -893,6 +893,20 @@ pub mod fooocus; feature = "endpoints_fal-ai_gemini-flash-edit" ))) )] +pub mod gemini_25_flash_image; +#[cfg(any( + feature = "endpoints", + feature = "endpoints_fal-ai", + feature = "endpoints_fal-ai_gemini-flash-edit" +))] +#[cfg_attr( + docsrs, + doc(cfg(any( + feature = "endpoints", + feature = "endpoints_fal-ai", + feature = "endpoints_fal-ai_gemini-flash-edit" + ))) +)] pub mod gemini_flash_edit; #[cfg(any( feature = "endpoints",