mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
seedance pro 1.0 cost
This commit is contained in:
1 parent
02cb7558e4
commit
efe56050c4
2 files changed
+93
-3
No files matched your search
+1
-1
@@ -86,7 +86,7 @@ impl <U: IntoUrl, T: IntoUrl, V: IntoUrl> 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<U: IntoUrl, T: IntoUrl, V: IntoUrl>(
|
||||
args: Seedance1LiteArgs<'_, U, T, V>
|
||||
|
||||
+92
-2
@@ -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<u32>,
|
||||
}
|
||||
|
||||
#[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 <U: IntoUrl, V: IntoUrl> 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<U: IntoUrl, V: IntoUrl>(
|
||||
args: Seedance1ProArgs<'_, U, V>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
@@ -84,11 +135,50 @@ pub async fn enqueue_seedance_1_pro_image_to_video_webhook<U: IntoUrl, V: IntoUr
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use crate::requests::webhook::video::image::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;
|
||||
|
||||
#[test]
|
||||
fn test_cost() {
|
||||
let api_key = FalApiKey::from_str("");
|
||||
|
||||
let mut args = Seedance1ProArgs {
|
||||
image_url: "",
|
||||
prompt: "",
|
||||
api_key: &api_key,
|
||||
camera_fixed: false,
|
||||
duration: Seedance1ProDuration::FiveSeconds,
|
||||
resolution: Seedance1ProResolution::TenEightyP,
|
||||
seed: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
// NB: Constant value specified by FAL
|
||||
args.duration = Seedance1ProDuration::FiveSeconds;
|
||||
args.resolution = Seedance1ProResolution::TenEightyP;
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 62);
|
||||
|
||||
// NB: Calculations follow...
|
||||
args.duration = Seedance1ProDuration::FiveSeconds;
|
||||
args.resolution = Seedance1ProResolution::SevenTwentyP;
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 34);
|
||||
|
||||
args.duration = Seedance1ProDuration::TenSeconds;
|
||||
args.resolution = Seedance1ProResolution::SevenTwentyP;
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 68);
|
||||
|
||||
args.duration = Seedance1ProDuration::TenSeconds;
|
||||
args.resolution = Seedance1ProResolution::TenEightyP;
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 152);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test() -> AnyhowResult<()> {
|
||||
|
||||
Reference in new issue
Block a user