mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-07 02:21:23 +00:00
improve types
This commit is contained in:
1 parent
ac6a69fa32
commit
75539a2026
12 files changed
+462
-61
No files matched your search
+1
@@ -36,6 +36,7 @@ pub(crate) fn estimate_video_cost_artcraft_kling3p0_pro(
|
||||
negative_prompt: None,
|
||||
duration,
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ pub(crate) fn estimate_video_cost_artcraft_kling3p0_standard(
|
||||
negative_prompt: None,
|
||||
duration,
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
+5
@@ -30,6 +30,11 @@ pub struct Kling3p0ProImageToVideoInput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<String>,
|
||||
|
||||
/// Shot type for multi-shot video generation.
|
||||
/// Possible enum values: "customize", "intelligent"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shot_type: Option<String>,
|
||||
|
||||
/// The CFG (Classifier Free Guidance) scale.
|
||||
/// Default value: 0.5
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
+5
@@ -23,6 +23,11 @@ pub struct Kling3p0ProTextToVideoInput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<String>,
|
||||
|
||||
/// Shot type for multi-shot video generation.
|
||||
/// Possible enum values: "customize", "intelligent"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shot_type: Option<String>,
|
||||
|
||||
/// The CFG (Classifier Free Guidance) scale.
|
||||
/// Default value: 0.5
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
+5
@@ -30,6 +30,11 @@ pub struct Kling3p0StandardImageToVideoInput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<String>,
|
||||
|
||||
/// Shot type for multi-shot video generation.
|
||||
/// Possible enum values: "customize", "intelligent"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shot_type: Option<String>,
|
||||
|
||||
/// The CFG (Classifier Free Guidance) scale.
|
||||
/// Default value: 0.5
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
+5
@@ -23,6 +23,11 @@ pub struct Kling3p0StandardTextToVideoInput {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<String>,
|
||||
|
||||
/// Shot type for multi-shot video generation.
|
||||
/// Possible enum values: "customize", "intelligent"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shot_type: Option<String>,
|
||||
|
||||
/// The CFG (Classifier Free Guidance) scale.
|
||||
/// Default value: 0.5
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
+157
-18
@@ -2,12 +2,12 @@ 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 crate::requests::webhook::video::text::enqueue_kling_3p0_pro_text_to_video_webhook::EnqueueKling3p0ProTextToVideoDuration;
|
||||
use crate::requests::http::video::http_kling_3p0_pro_image_to_video::{kling_3p0_pro_image_to_video, Kling3p0ProImageToVideoInput};
|
||||
use fal::webhook::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKling3p0ProImageToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub image_url: String,
|
||||
|
||||
@@ -15,28 +15,91 @@ pub struct EnqueueKling3p0ProImageToVideoArgs<'a, R: IntoUrl> {
|
||||
pub end_image_url: Option<String>,
|
||||
pub generate_audio: Option<bool>,
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKling3p0ProTextToVideoDuration>,
|
||||
pub duration: Option<EnqueueKling3p0ProImageToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0ProImageToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0ProImageToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0ProImageToVideoDuration {
|
||||
ThreeSeconds,
|
||||
FourSeconds,
|
||||
FiveSeconds,
|
||||
SixSeconds,
|
||||
SevenSeconds,
|
||||
EightSeconds,
|
||||
NineSeconds,
|
||||
TenSeconds,
|
||||
ElevenSeconds,
|
||||
TwelveSeconds,
|
||||
ThirteenSeconds,
|
||||
FourteenSeconds,
|
||||
FifteenSeconds,
|
||||
}
|
||||
|
||||
impl EnqueueKling3p0ProImageToVideoDuration {
|
||||
pub fn to_seconds(&self) -> u64 {
|
||||
match self {
|
||||
Self::ThreeSeconds => 3,
|
||||
Self::FourSeconds => 4,
|
||||
Self::FiveSeconds => 5,
|
||||
Self::SixSeconds => 6,
|
||||
Self::SevenSeconds => 7,
|
||||
Self::EightSeconds => 8,
|
||||
Self::NineSeconds => 9,
|
||||
Self::TenSeconds => 10,
|
||||
Self::ElevenSeconds => 11,
|
||||
Self::TwelveSeconds => 12,
|
||||
Self::ThirteenSeconds => 13,
|
||||
Self::FourteenSeconds => 14,
|
||||
Self::FifteenSeconds => 15,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::ThreeSeconds => "3",
|
||||
Self::FourSeconds => "4",
|
||||
Self::FiveSeconds => "5",
|
||||
Self::SixSeconds => "6",
|
||||
Self::SevenSeconds => "7",
|
||||
Self::EightSeconds => "8",
|
||||
Self::NineSeconds => "9",
|
||||
Self::TenSeconds => "10",
|
||||
Self::ElevenSeconds => "11",
|
||||
Self::TwelveSeconds => "12",
|
||||
Self::ThirteenSeconds => "13",
|
||||
Self::FourteenSeconds => "14",
|
||||
Self::FifteenSeconds => "15",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0ProImageToVideoAspectRatio {
|
||||
Square,
|
||||
SixteenByNine,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0ProImageToVideoShotType {
|
||||
Customize,
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0ProImageToVideoArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Fal Docs:
|
||||
// For every second of video you generated, you will be charged $0.224 (audio off)
|
||||
// or $0.336 (audio on),
|
||||
// if voice control is used while generating audio you will be charged $0.392.
|
||||
// For example, a 5s video with audio on and voice control will cost $1.96
|
||||
|
||||
// Our Docs:
|
||||
// Same pricing as text-to-video for Kling 3.0 Pro:
|
||||
// Audio off: $0.224/second
|
||||
// Audio on: $0.336/second
|
||||
let generate_audio = self.generate_audio.unwrap_or(true);
|
||||
let duration_secs = self.duration
|
||||
.unwrap_or(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds)
|
||||
.unwrap_or(EnqueueKling3p0ProImageToVideoDuration::FiveSeconds)
|
||||
.to_seconds();
|
||||
|
||||
let rate = if generate_audio { 336u64 } else { 224u64 };
|
||||
@@ -53,14 +116,30 @@ pub async fn enqueue_kling_3p0_pro_image_to_video_webhook<R: IntoUrl>(
|
||||
let duration = args.duration
|
||||
.map(|d| d.to_str().to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
.map(|ar| match ar {
|
||||
EnqueueKling3p0ProImageToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKling3p0ProImageToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
EnqueueKling3p0ProImageToVideoAspectRatio::NineBySixteen => "9:16",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0ProImageToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0ProImageToVideoShotType::Intelligent => "intelligent",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0ProImageToVideoInput {
|
||||
prompt: args.prompt,
|
||||
image_url: args.image_url,
|
||||
end_image_url: args.end_image_url,
|
||||
aspect_ratio: None,
|
||||
aspect_ratio,
|
||||
generate_audio: args.generate_audio,
|
||||
duration,
|
||||
negative_prompt: args.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
|
||||
@@ -92,7 +171,9 @@ mod tests {
|
||||
end_image_url: None,
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
duration: Some(EnqueueKling3p0ProImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
@@ -102,22 +183,22 @@ mod tests {
|
||||
assert_eq!(args.calculate_cost_in_cents(), 112);
|
||||
|
||||
// 10s: (224 * 10 + 9) / 10 = 2249 / 10 = 224
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0ProImageToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 224);
|
||||
|
||||
// 15s: (224 * 15 + 9) / 10 = 3369 / 10 = 336
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0ProImageToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 336);
|
||||
|
||||
// Audio on: $0.336/sec
|
||||
args.generate_audio = Some(true);
|
||||
|
||||
// 5s: (336 * 5 + 9) / 10 = 1689 / 10 = 168
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds);
|
||||
args.duration = Some(EnqueueKling3p0ProImageToVideoDuration::FiveSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 168);
|
||||
|
||||
// 10s: (336 * 10 + 9) / 10 = 3369 / 10 = 336
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0ProImageToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 336);
|
||||
}
|
||||
|
||||
@@ -130,10 +211,12 @@ mod tests {
|
||||
let args = EnqueueKling3p0ProImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the t-rex skeleton gets off the podium and begins walking to the camera, then bites".to_string(),
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
duration: Some(EnqueueKling3p0ProImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -144,21 +227,77 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_aspect_ratios() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for ar in EnqueueKling3p0ProImageToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueKling3p0ProImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton comes alive and roars at the camera".to_string(),
|
||||
duration: Some(EnqueueKling3p0ProImageToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_pro_image_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_durations() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for dur in EnqueueKling3p0ProTextToVideoDuration::iter() {
|
||||
for dur in EnqueueKling3p0ProImageToVideoDuration::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueKling3p0ProImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton slowly turns its head and roars".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_pro_image_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_shot_types() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for st in EnqueueKling3p0ProImageToVideoShotType::iter() {
|
||||
println!("--- shot type: {:?} ---", st);
|
||||
let args = EnqueueKling3p0ProImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton lurches forward and snaps its jaws".to_string(),
|
||||
duration: Some(EnqueueKling3p0ProImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: Some(st),
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+157
-11
@@ -2,12 +2,12 @@ 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 crate::requests::webhook::video::text::enqueue_kling_3p0_standard_text_to_video_webhook::EnqueueKling3p0StandardTextToVideoDuration;
|
||||
use crate::requests::http::video::http_kling_3p0_standard_image_to_video::{kling_3p0_standard_image_to_video, Kling3p0StandardImageToVideoInput};
|
||||
use fal::webhook::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKling3p0StandardImageToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub image_url: String,
|
||||
|
||||
@@ -15,13 +15,83 @@ pub struct EnqueueKling3p0StandardImageToVideoArgs<'a, R: IntoUrl> {
|
||||
pub end_image_url: Option<String>,
|
||||
pub generate_audio: Option<bool>,
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKling3p0StandardTextToVideoDuration>,
|
||||
pub duration: Option<EnqueueKling3p0StandardImageToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0StandardImageToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0StandardImageToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0StandardImageToVideoDuration {
|
||||
ThreeSeconds,
|
||||
FourSeconds,
|
||||
FiveSeconds,
|
||||
SixSeconds,
|
||||
SevenSeconds,
|
||||
EightSeconds,
|
||||
NineSeconds,
|
||||
TenSeconds,
|
||||
ElevenSeconds,
|
||||
TwelveSeconds,
|
||||
ThirteenSeconds,
|
||||
FourteenSeconds,
|
||||
FifteenSeconds,
|
||||
}
|
||||
|
||||
impl EnqueueKling3p0StandardImageToVideoDuration {
|
||||
pub fn to_seconds(&self) -> u64 {
|
||||
match self {
|
||||
Self::ThreeSeconds => 3,
|
||||
Self::FourSeconds => 4,
|
||||
Self::FiveSeconds => 5,
|
||||
Self::SixSeconds => 6,
|
||||
Self::SevenSeconds => 7,
|
||||
Self::EightSeconds => 8,
|
||||
Self::NineSeconds => 9,
|
||||
Self::TenSeconds => 10,
|
||||
Self::ElevenSeconds => 11,
|
||||
Self::TwelveSeconds => 12,
|
||||
Self::ThirteenSeconds => 13,
|
||||
Self::FourteenSeconds => 14,
|
||||
Self::FifteenSeconds => 15,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::ThreeSeconds => "3",
|
||||
Self::FourSeconds => "4",
|
||||
Self::FiveSeconds => "5",
|
||||
Self::SixSeconds => "6",
|
||||
Self::SevenSeconds => "7",
|
||||
Self::EightSeconds => "8",
|
||||
Self::NineSeconds => "9",
|
||||
Self::TenSeconds => "10",
|
||||
Self::ElevenSeconds => "11",
|
||||
Self::TwelveSeconds => "12",
|
||||
Self::ThirteenSeconds => "13",
|
||||
Self::FourteenSeconds => "14",
|
||||
Self::FifteenSeconds => "15",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0StandardImageToVideoAspectRatio {
|
||||
Square,
|
||||
SixteenByNine,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0StandardImageToVideoShotType {
|
||||
Customize,
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0StandardImageToVideoArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Same pricing as text-to-video for Kling 3.0 Standard:
|
||||
@@ -29,7 +99,7 @@ impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0StandardImageToVid
|
||||
// Audio on: $0.252/second
|
||||
let generate_audio = self.generate_audio.unwrap_or(true);
|
||||
let duration_secs = self.duration
|
||||
.unwrap_or(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds)
|
||||
.unwrap_or(EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds)
|
||||
.to_seconds();
|
||||
|
||||
let rate = if generate_audio { 252u64 } else { 168u64 };
|
||||
@@ -46,14 +116,30 @@ pub async fn enqueue_kling_3p0_standard_image_to_video_webhook<R: IntoUrl>(
|
||||
let duration = args.duration
|
||||
.map(|d| d.to_str().to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
.map(|ar| match ar {
|
||||
EnqueueKling3p0StandardImageToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKling3p0StandardImageToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
EnqueueKling3p0StandardImageToVideoAspectRatio::NineBySixteen => "9:16",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0StandardImageToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0StandardImageToVideoShotType::Intelligent => "intelligent",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0StandardImageToVideoInput {
|
||||
prompt: args.prompt,
|
||||
image_url: args.image_url,
|
||||
end_image_url: args.end_image_url,
|
||||
aspect_ratio: None, // Not applicable for image-to-video
|
||||
aspect_ratio,
|
||||
generate_audio: args.generate_audio,
|
||||
duration,
|
||||
negative_prompt: args.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
|
||||
@@ -85,7 +171,9 @@ mod tests {
|
||||
end_image_url: None,
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
duration: Some(EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
@@ -95,22 +183,22 @@ mod tests {
|
||||
assert_eq!(args.calculate_cost_in_cents(), 84);
|
||||
|
||||
// 10s: (168 * 10 + 9) / 10 = 1689 / 10 = 168
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0StandardImageToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 168);
|
||||
|
||||
// 15s: (168 * 15 + 9) / 10 = 2529 / 10 = 252
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0StandardImageToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 252);
|
||||
|
||||
// Audio on: $0.252/sec
|
||||
args.generate_audio = Some(true);
|
||||
|
||||
// 5s: (252 * 5 + 9) / 10 = 1269 / 10 = 126
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds);
|
||||
args.duration = Some(EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 126);
|
||||
|
||||
// 10s: (252 * 10 + 9) / 10 = 2529 / 10 = 252
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
args.duration = Some(EnqueueKling3p0StandardImageToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 252);
|
||||
}
|
||||
|
||||
@@ -123,10 +211,12 @@ mod tests {
|
||||
let args = EnqueueKling3p0StandardImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the t-rex skeleton gets off the podium and begins walking toward the camera".to_string(),
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
duration: Some(EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -137,21 +227,77 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_aspect_ratios() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for ar in EnqueueKling3p0StandardImageToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueKling3p0StandardImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton comes alive and roars at the camera".to_string(),
|
||||
duration: Some(EnqueueKling3p0StandardImageToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_standard_image_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_durations() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for dur in EnqueueKling3p0StandardTextToVideoDuration::iter() {
|
||||
for dur in EnqueueKling3p0StandardImageToVideoDuration::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueKling3p0StandardImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton slowly turns its head and opens its jaw".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_standard_image_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_shot_types() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for st in EnqueueKling3p0StandardImageToVideoShotType::iter() {
|
||||
println!("--- shot type: {:?} ---", st);
|
||||
let args = EnqueueKling3p0StandardImageToVideoArgs {
|
||||
image_url: TREX_SKELETON_IMAGE_URL.to_string(),
|
||||
prompt: "the skeleton lurches forward dramatically".to_string(),
|
||||
duration: Some(EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardImageToVideoAspectRatio::SixteenByNine),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
end_image_url: None,
|
||||
shot_type: Some(st),
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+44
@@ -14,6 +14,7 @@ pub struct EnqueueKling3p0ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKling3p0ProTextToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0ProTextToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0ProTextToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
@@ -82,6 +83,12 @@ pub enum EnqueueKling3p0ProTextToVideoAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0ProTextToVideoShotType {
|
||||
Customize,
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0ProTextToVideoArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Kling 3.0 Pro pricing:
|
||||
@@ -114,12 +121,20 @@ pub async fn enqueue_kling_3p0_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0ProTextToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0ProTextToVideoShotType::Intelligent => "intelligent",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
|
||||
@@ -150,6 +165,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
@@ -198,6 +214,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -222,6 +239,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -246,6 +264,32 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_pro_text_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_shot_types() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for st in EnqueueKling3p0ProTextToVideoShotType::iter() {
|
||||
println!("--- shot type: {:?} ---", st);
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
prompt: "an eagle soars over a snow-capped mountain range".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: Some(st),
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+44
@@ -14,6 +14,7 @@ pub struct EnqueueKling3p0StandardTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKling3p0StandardTextToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0StandardTextToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0StandardTextToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
@@ -82,6 +83,12 @@ pub enum EnqueueKling3p0StandardTextToVideoAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
pub enum EnqueueKling3p0StandardTextToVideoShotType {
|
||||
Customize,
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0StandardTextToVideoArgs<'_, U> {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Kling 3.0 Standard pricing:
|
||||
@@ -115,12 +122,20 @@ pub async fn enqueue_kling_3p0_standard_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0StandardTextToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0StandardTextToVideoShotType::Intelligent => "intelligent",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0StandardTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
|
||||
@@ -151,6 +166,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
@@ -199,6 +215,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -223,6 +240,7 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -247,6 +265,32 @@ mod tests {
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
let result = enqueue_kling_3p0_standard_text_to_video_webhook(args).await?;
|
||||
println!("result: {:?}", result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore] // manually run — fires a real API request per variant (expensive)
|
||||
async fn test_all_shot_types() -> AnyhowResult<()> {
|
||||
let secret = read_to_string("/Users/bt/Artcraft/credentials/fal_api_key.txt")?;
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
for st in EnqueueKling3p0StandardTextToVideoShotType::iter() {
|
||||
println!("--- shot type: {:?} ---", st);
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
prompt: "a bird takes flight from a tree branch".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: Some(st),
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+19
-16
@@ -21,7 +21,7 @@ use enums::common::model_type::ModelType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use fal_client::creds::open_ai_api_key::OpenAiApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_pro_image_to_video_webhook::{enqueue_kling_3p0_pro_image_to_video_webhook, EnqueueKling3p0ProImageToVideoArgs};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_pro_image_to_video_webhook::{enqueue_kling_3p0_pro_image_to_video_webhook, EnqueueKling3p0ProImageToVideoArgs, EnqueueKling3p0ProImageToVideoDuration};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_pro_text_to_video_webhook::{enqueue_kling_3p0_pro_text_to_video_webhook, EnqueueKling3p0ProTextToVideoArgs, EnqueueKling3p0ProTextToVideoAspectRatio, EnqueueKling3p0ProTextToVideoDuration};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
@@ -40,22 +40,22 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
fn map_duration_i2v(duration: Option<Kling3p0ProMultiFunctionVideoGenDuration>) -> EnqueueKling3p0ProTextToVideoDuration {
|
||||
fn map_duration_i2v(duration: Option<Kling3p0ProMultiFunctionVideoGenDuration>) -> EnqueueKling3p0ProImageToVideoDuration {
|
||||
match duration {
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ThreeSeconds) => EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FourSeconds) => EnqueueKling3p0ProTextToVideoDuration::FourSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FiveSeconds) => EnqueueKling3p0ProTextToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::SixSeconds) => EnqueueKling3p0ProTextToVideoDuration::SixSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::SevenSeconds) => EnqueueKling3p0ProTextToVideoDuration::SevenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::EightSeconds) => EnqueueKling3p0ProTextToVideoDuration::EightSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::NineSeconds) => EnqueueKling3p0ProTextToVideoDuration::NineSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::TenSeconds) => EnqueueKling3p0ProTextToVideoDuration::TenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ElevenSeconds) => EnqueueKling3p0ProTextToVideoDuration::ElevenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::TwelveSeconds) => EnqueueKling3p0ProTextToVideoDuration::TwelveSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ThirteenSeconds) => EnqueueKling3p0ProTextToVideoDuration::ThirteenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FourteenSeconds) => EnqueueKling3p0ProTextToVideoDuration::FourteenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FifteenSeconds) => EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds,
|
||||
None => EnqueueKling3p0ProTextToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ThreeSeconds) => EnqueueKling3p0ProImageToVideoDuration::ThreeSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FourSeconds) => EnqueueKling3p0ProImageToVideoDuration::FourSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FiveSeconds) => EnqueueKling3p0ProImageToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::SixSeconds) => EnqueueKling3p0ProImageToVideoDuration::SixSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::SevenSeconds) => EnqueueKling3p0ProImageToVideoDuration::SevenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::EightSeconds) => EnqueueKling3p0ProImageToVideoDuration::EightSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::NineSeconds) => EnqueueKling3p0ProImageToVideoDuration::NineSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::TenSeconds) => EnqueueKling3p0ProImageToVideoDuration::TenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ElevenSeconds) => EnqueueKling3p0ProImageToVideoDuration::ElevenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::TwelveSeconds) => EnqueueKling3p0ProImageToVideoDuration::TwelveSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::ThirteenSeconds) => EnqueueKling3p0ProImageToVideoDuration::ThirteenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FourteenSeconds) => EnqueueKling3p0ProImageToVideoDuration::FourteenSeconds,
|
||||
Some(Kling3p0ProMultiFunctionVideoGenDuration::FifteenSeconds) => EnqueueKling3p0ProImageToVideoDuration::FifteenSeconds,
|
||||
None => EnqueueKling3p0ProImageToVideoDuration::FiveSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,8 @@ pub async fn kling_3p0_pro_multi_function_video_gen_handler(
|
||||
generate_audio: request.generate_audio,
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
@@ -241,6 +243,7 @@ pub async fn kling_3p0_pro_multi_function_video_gen_handler(
|
||||
generate_audio: request.generate_audio,
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
shot_type: None,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
+19
-16
@@ -21,7 +21,7 @@ use enums::common::model_type::ModelType;
|
||||
use enums::common::visibility::Visibility;
|
||||
use fal_client::creds::open_ai_api_key::OpenAiApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_standard_image_to_video_webhook::{enqueue_kling_3p0_standard_image_to_video_webhook, EnqueueKling3p0StandardImageToVideoArgs};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_3p0_standard_image_to_video_webhook::{enqueue_kling_3p0_standard_image_to_video_webhook, EnqueueKling3p0StandardImageToVideoArgs, EnqueueKling3p0StandardImageToVideoDuration};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_standard_text_to_video_webhook::{enqueue_kling_3p0_standard_text_to_video_webhook, EnqueueKling3p0StandardTextToVideoArgs, EnqueueKling3p0StandardTextToVideoAspectRatio, EnqueueKling3p0StandardTextToVideoDuration};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
@@ -40,22 +40,22 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
fn map_duration_i2v(duration: Option<Kling3p0StandardMultiFunctionVideoGenDuration>) -> EnqueueKling3p0StandardTextToVideoDuration {
|
||||
fn map_duration_i2v(duration: Option<Kling3p0StandardMultiFunctionVideoGenDuration>) -> EnqueueKling3p0StandardImageToVideoDuration {
|
||||
match duration {
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ThreeSeconds) => EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FourSeconds) => EnqueueKling3p0StandardTextToVideoDuration::FourSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FiveSeconds) => EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::SixSeconds) => EnqueueKling3p0StandardTextToVideoDuration::SixSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::SevenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::SevenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::EightSeconds) => EnqueueKling3p0StandardTextToVideoDuration::EightSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::NineSeconds) => EnqueueKling3p0StandardTextToVideoDuration::NineSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::TenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::TenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ElevenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::ElevenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::TwelveSeconds) => EnqueueKling3p0StandardTextToVideoDuration::TwelveSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ThirteenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::ThirteenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FourteenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::FourteenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FifteenSeconds) => EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds,
|
||||
None => EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ThreeSeconds) => EnqueueKling3p0StandardImageToVideoDuration::ThreeSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FourSeconds) => EnqueueKling3p0StandardImageToVideoDuration::FourSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FiveSeconds) => EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::SixSeconds) => EnqueueKling3p0StandardImageToVideoDuration::SixSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::SevenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::SevenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::EightSeconds) => EnqueueKling3p0StandardImageToVideoDuration::EightSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::NineSeconds) => EnqueueKling3p0StandardImageToVideoDuration::NineSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::TenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::TenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ElevenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::ElevenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::TwelveSeconds) => EnqueueKling3p0StandardImageToVideoDuration::TwelveSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::ThirteenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::ThirteenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FourteenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::FourteenSeconds,
|
||||
Some(Kling3p0StandardMultiFunctionVideoGenDuration::FifteenSeconds) => EnqueueKling3p0StandardImageToVideoDuration::FifteenSeconds,
|
||||
None => EnqueueKling3p0StandardImageToVideoDuration::FiveSeconds,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,8 @@ pub async fn kling_3p0_standard_multi_function_video_gen_handler(
|
||||
generate_audio: request.generate_audio,
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
@@ -241,6 +243,7 @@ pub async fn kling_3p0_standard_multi_function_video_gen_handler(
|
||||
generate_audio: request.generate_audio,
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
shot_type: None,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user