From efe56050c435e907fd8b212efc8a6a918083c837 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 29 Dec 2025 01:17:57 -0500 Subject: [PATCH] seedance pro 1.0 cost --- ..._seedance_1_lite_image_to_video_webhook.rs | 2 +- ...e_seedance_1_pro_image_to_video_webhook.rs | 94 ++++++++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_lite_image_to_video_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_lite_image_to_video_webhook.rs index 6e95bcb3f9..c0e173eb75 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_lite_image_to_video_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_lite_image_to_video_webhook.rs @@ -86,7 +86,7 @@ impl FalRequestCostCalculator for Seedance1 } -/// Seedance 1 Lite Image-to-Video +/// Seedance 1.0 Lite Image-to-Video /// https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/image-to-video pub async fn enqueue_seedance_1_lite_image_to_video_webhook( args: Seedance1LiteArgs<'_, U, T, V> diff --git a/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_pro_image_to_video_webhook.rs b/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_pro_image_to_video_webhook.rs index 5c2c76d532..2a16be5797 100644 --- a/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_pro_image_to_video_webhook.rs +++ b/crates/api_clients/fal_client/src/requests/webhook/video/image/enqueue_seedance_1_pro_image_to_video_webhook.rs @@ -1,6 +1,7 @@ use crate::creds::fal_api_key::FalApiKey; use crate::error::classify_fal_error::classify_fal_error; use crate::error::fal_error_plus::FalErrorPlus; +use crate::requests::traits::fal_request_cost_calculator_trait::{FalRequestCostCalculator, UsdCents}; use fal::endpoints::fal_ai::bytedance::seedance::v1::pro::image_to_video::{seedance_v1_pro_image_to_video, SeedanceImageToVideoProRequest}; use fal::webhook::WebhookResponse; use reqwest::IntoUrl; @@ -16,7 +17,7 @@ pub struct Seedance1ProArgs<'a, U: IntoUrl, V: IntoUrl> { pub seed: Option, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Seedance1ProDuration { ThreeSeconds, FourSeconds, @@ -30,13 +31,63 @@ pub enum Seedance1ProDuration { TwelveSeconds, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Seedance1ProResolution { FourEightyP, // 480p SevenTwentyP, // 720p TenEightyP, // 1080p } + +impl FalRequestCostCalculator for Seedance1ProArgs<'_, U, V> { + fn calculate_cost_in_cents(&self) -> UsdCents { + // "Each 1080p 5 second video costs roughly $0.62. + // For other resolutions, 1 million video tokens costs $2.5. + // tokens(video) = (height x width x FPS x duration) / 1024." + + if self.resolution == Seedance1ProResolution::TenEightyP + && self.duration == Seedance1ProDuration::FiveSeconds + { + return 62; + } + + // TODO: Only correct for some aspect ratios for now. + let (width, height) = match self.resolution { + Seedance1ProResolution::FourEightyP => (640u32, 480u32), // NB: Only for 4:3 ! + Seedance1ProResolution::SevenTwentyP => (1280, 720), // NB: Only for 16:9 ! + Seedance1ProResolution::TenEightyP => (1920, 1080), + }; + + let duration = match self.duration { + Seedance1ProDuration::ThreeSeconds => 3.0, + Seedance1ProDuration::FourSeconds => 4.0, + Seedance1ProDuration::FiveSeconds => 5.0, + Seedance1ProDuration::SixSeconds => 6.0, + Seedance1ProDuration::SevenSeconds => 7.0, + Seedance1ProDuration::EightSeconds => 8.0, + Seedance1ProDuration::NineSeconds => 9.0, + Seedance1ProDuration::TenSeconds => 10.0, + Seedance1ProDuration::ElevenSeconds => 11.0, + Seedance1ProDuration::TwelveSeconds => 12.0, + }; + + // TODO: Not sure if FPS is right. + // Inferred from https://help.scenario.com/en/articles/seedance-models-the-essentials/ + const FPS : f64 = 30.0; + + let tokens = (height as f64) * (width as f64) * FPS * duration; + let tokens = tokens / 1024.0; + + let cost = tokens * 2.5 / 1_000_000.0; + let cost = cost * 100.0; // Dollars to cents. + let cost = cost.ceil(); // NB: This is probably what Fal does. + + cost as UsdCents + } +} + +/// Seedance 1.0 Pro Image-to-Video +/// https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/image-to-video pub async fn enqueue_seedance_1_pro_image_to_video_webhook( args: Seedance1ProArgs<'_, U, V> ) -> Result { @@ -84,11 +135,50 @@ pub async fn enqueue_seedance_1_pro_image_to_video_webhook AnyhowResult<()> {