mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-11 12:23:20 +00:00
video models
This commit is contained in:
1 parent
94383d9928
commit
84d7e3b94f
35 files changed
+633
-501
No files matched your search
+3
-6
@@ -1,7 +1,7 @@
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_3p0_pro_multi_function_video_gen::Kling3p0ProMultiFunctionVideoGenDuration;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_pro_text_to_video_webhook::{
|
||||
EnqueueKling3p0ProTextToVideoArgs,
|
||||
EnqueueKling3p0ProTextToVideoRequest,
|
||||
EnqueueKling3p0ProTextToVideoDuration,
|
||||
};
|
||||
|
||||
@@ -29,19 +29,16 @@ pub(crate) fn estimate_video_cost_artcraft_kling3p0_pro(
|
||||
});
|
||||
|
||||
// Use text-to-video cost calculator (same pricing for both modes)
|
||||
let api_key = fal_client::creds::fal_api_key::FalApiKey::from_str("");
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
let req = EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: None,
|
||||
duration,
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
let cost_in_usd_cents = req.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
|
||||
+3
-6
@@ -1,7 +1,7 @@
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_3p0_standard_multi_function_video_gen::Kling3p0StandardMultiFunctionVideoGenDuration;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_3p0_standard_text_to_video_webhook::{
|
||||
EnqueueKling3p0StandardTextToVideoArgs,
|
||||
EnqueueKling3p0StandardTextToVideoRequest,
|
||||
EnqueueKling3p0StandardTextToVideoDuration,
|
||||
};
|
||||
|
||||
@@ -29,19 +29,16 @@ pub(crate) fn estimate_video_cost_artcraft_kling3p0_standard(
|
||||
});
|
||||
|
||||
// Use text-to-video cost calculator (same pricing for both modes)
|
||||
let api_key = fal_client::creds::fal_api_key::FalApiKey::from_str("");
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
let req = EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: None,
|
||||
duration,
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
let cost_in_usd_cents = req.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
|
||||
+3
-6
@@ -1,7 +1,7 @@
|
||||
use artcraft_api_defs::generate::video::multi_function::seedance_1p5_pro_multi_function_video_gen::Seedance1p5ProMultiFunctionVideoGenDuration;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::text::enqueue_seedance_1p5_pro_text_to_video_webhook::{
|
||||
EnqueueSeedance1p5ProTextToVideoArgs,
|
||||
EnqueueSeedance1p5ProTextToVideoRequest,
|
||||
EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
};
|
||||
@@ -33,18 +33,15 @@ pub(crate) fn estimate_video_cost_artcraft_seedance1p5_pro(
|
||||
});
|
||||
|
||||
// Use text-to-video cost calculator (same pricing for both modes)
|
||||
let api_key = fal_client::creds::fal_api_key::FalApiKey::from_str("");
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
let req = EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
duration,
|
||||
resolution,
|
||||
aspect_ratio: None,
|
||||
generate_audio: plan.generate_audio,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
let cost_in_usd_cents = req.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
|
||||
+3
-7
@@ -1,7 +1,6 @@
|
||||
use fal_client::creds::fal_api_key::FalApiKey;
|
||||
use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestCostCalculator;
|
||||
use fal_client::requests::webhook::video::text::enqueue_seedance_1p5_pro_text_to_video_webhook::{
|
||||
EnqueueSeedance1p5ProTextToVideoArgs, EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoRequest, EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
@@ -15,18 +14,15 @@ pub(crate) fn estimate_video_cost_fal_seedance_1p5_pro(
|
||||
) -> VideoGenerationCostEstimate {
|
||||
// Seedance 1.5 Pro t2v and i2v have identical pricing; delegate to the t2v
|
||||
// calculator to guarantee parity with billing.
|
||||
let api_key = FalApiKey::from_str("");
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
let req = EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: None,
|
||||
generate_audio: plan.generate_audio,
|
||||
webhook_url: "https://example.com",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = args.calculate_cost_in_cents();
|
||||
let cost_in_usd_cents = req.calculate_cost_in_cents();
|
||||
|
||||
VideoGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
|
||||
+8
-5
@@ -14,7 +14,8 @@ use fal_client::requests::webhook::video::image::enqueue_kling_v2p5_turbo_pro_im
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{
|
||||
enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs,
|
||||
EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds,
|
||||
EnqueueKlingV2p5TurboProTextToVideoRequest, EnqueueKlingV2p5TurboProTextToVideoAspectRatio,
|
||||
EnqueueKlingV2p5TurboProTextToVideoDurationSeconds,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_5_turbo_pro(
|
||||
@@ -24,10 +25,12 @@ pub async fn execute_fal_kling_2_5_turbo_pro(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling2p5TurboProMode::TextToVideo => {
|
||||
let args = EnqueueKlingV2p5TurboProTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
request: EnqueueKlingV2p5TurboProTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+9
-6
@@ -13,7 +13,8 @@ use fal_client::requests::webhook::video::image::enqueue_kling_v2p6_pro_image_to
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{
|
||||
enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs,
|
||||
EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds,
|
||||
EnqueueKlingV2p6ProTextToVideoRequest, EnqueueKlingV2p6ProTextToVideoAspectRatio,
|
||||
EnqueueKlingV2p6ProTextToVideoDurationSeconds,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_2_6_pro(
|
||||
@@ -23,11 +24,13 @@ pub async fn execute_fal_kling_2_6_pro(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling2p6ProMode::TextToVideo => {
|
||||
let args = EnqueueKlingV2p6ProTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
request: EnqueueKlingV2p6ProTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+10
-7
@@ -14,7 +14,8 @@ use fal_client::requests::webhook::video::image::enqueue_kling_3p0_pro_image_to_
|
||||
};
|
||||
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,
|
||||
EnqueueKling3p0ProTextToVideoRequest, EnqueueKling3p0ProTextToVideoAspectRatio,
|
||||
EnqueueKling3p0ProTextToVideoDuration,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_3p0_pro(
|
||||
@@ -24,12 +25,14 @@ pub async fn execute_fal_kling_3p0_pro(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling3p0Mode::TextToVideo => {
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
shot_type: None,
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+10
-7
@@ -15,7 +15,8 @@ use fal_client::requests::webhook::video::image::enqueue_kling_3p0_standard_imag
|
||||
};
|
||||
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,
|
||||
EnqueueKling3p0StandardTextToVideoRequest, EnqueueKling3p0StandardTextToVideoAspectRatio,
|
||||
EnqueueKling3p0StandardTextToVideoDuration,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_kling_3p0_standard(
|
||||
@@ -25,12 +26,14 @@ pub async fn execute_fal_kling_3p0_standard(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalKling3p0Mode::TextToVideo => {
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
generate_audio: plan.generate_audio,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
shot_type: None,
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+9
-7
@@ -15,8 +15,8 @@ use fal_client::requests::webhook::video::image::enqueue_seedance_1p5_pro_image_
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_seedance_1p5_pro_text_to_video_webhook::{
|
||||
enqueue_seedance_1p5_pro_text_to_video_webhook, EnqueueSeedance1p5ProTextToVideoArgs,
|
||||
EnqueueSeedance1p5ProTextToVideoAspectRatio, EnqueueSeedance1p5ProTextToVideoDuration,
|
||||
EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
EnqueueSeedance1p5ProTextToVideoRequest, EnqueueSeedance1p5ProTextToVideoAspectRatio,
|
||||
EnqueueSeedance1p5ProTextToVideoDuration, EnqueueSeedance1p5ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_seedance_1p5_pro(
|
||||
@@ -26,11 +26,13 @@ pub async fn execute_fal_seedance_1p5_pro(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalSeedance1p5ProMode::TextToVideo => {
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
generate_audio: plan.generate_audio,
|
||||
request: EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
generate_audio: plan.generate_audio,
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+8
-6
@@ -14,8 +14,8 @@ use fal_client::requests::webhook::video::image::enqueue_sora_2_image_to_video_w
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_text_to_video_webhook::{
|
||||
enqueue_sora_2_text_to_video_webhook, EnqueueSora2TextToVideoArgs,
|
||||
EnqueueSora2TextToVideoAspectRatio, EnqueueSora2TextToVideoDurationSeconds,
|
||||
EnqueueSora2TextToVideoResolution,
|
||||
EnqueueSora2TextToVideoRequest, EnqueueSora2TextToVideoAspectRatio,
|
||||
EnqueueSora2TextToVideoDurationSeconds, EnqueueSora2TextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_sora_2(
|
||||
@@ -26,10 +26,12 @@ pub async fn execute_fal_sora_2(
|
||||
FalSora2Mode::TextToVideo => {
|
||||
// Text-to-video does not support Auto aspect ratio or Auto resolution.
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.and_then(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio),
|
||||
request: EnqueueSora2TextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.and_then(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio),
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+8
-6
@@ -15,8 +15,8 @@ use fal_client::requests::webhook::video::image::enqueue_sora_2_pro_image_to_vid
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_pro_text_to_video_webhook::{
|
||||
enqueue_sora_2_pro_text_to_video_webhook, EnqueueSora2ProTextToVideoArgs,
|
||||
EnqueueSora2ProTextToVideoAspectRatio, EnqueueSora2ProTextToVideoDurationSeconds,
|
||||
EnqueueSora2ProTextToVideoResolution,
|
||||
EnqueueSora2ProTextToVideoRequest, EnqueueSora2ProTextToVideoAspectRatio,
|
||||
EnqueueSora2ProTextToVideoDurationSeconds, EnqueueSora2ProTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_sora_2_pro(
|
||||
@@ -27,10 +27,12 @@ pub async fn execute_fal_sora_2_pro(
|
||||
FalSora2ProMode::TextToVideo => {
|
||||
// Text-to-video does not support Auto aspect ratio or Auto resolution.
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.and_then(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio),
|
||||
request: EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
resolution: plan.resolution.and_then(to_t2v_resolution),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.and_then(to_t2v_aspect_ratio),
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+7
-5
@@ -11,7 +11,7 @@ use fal_client::requests::webhook::video::image::enqueue_veo_2_image_to_video_we
|
||||
enqueue_veo_2_image_to_video_webhook, Veo2Args, Veo2AspectRatio, Veo2Request,
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_2_text_to_video_webhook::{
|
||||
enqueue_veo_2_text_to_video_webhook, Veo2TextToVideoArgs,
|
||||
enqueue_veo_2_text_to_video_webhook, Veo2TextToVideoArgs, Veo2TextToVideoRequest,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_2(
|
||||
@@ -21,11 +21,13 @@ pub async fn execute_fal_veo_2(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalVeo2Mode::TextToVideo => {
|
||||
let args = Veo2TextToVideoArgs {
|
||||
prompt: plan.prompt.as_str(),
|
||||
negative_prompt: plan.negative_prompt.as_deref(),
|
||||
request: Veo2TextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio.unwrap_or(Veo2AspectRatio::Auto),
|
||||
},
|
||||
api_key: &fal_client.api_key,
|
||||
duration: plan.duration,
|
||||
aspect_ratio: plan.aspect_ratio.unwrap_or(Veo2AspectRatio::Auto),
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
enqueue_veo_2_text_to_video_webhook(args)
|
||||
|
||||
+9
-7
@@ -14,7 +14,7 @@ use fal_client::requests::webhook::video::image::enqueue_veo_3_image_to_video_we
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3_text_to_video_webhook::{
|
||||
enqueue_veo_3_text_to_video_webhook, Veo3T2vAspectRatio, Veo3T2vDuration, Veo3T2vResolution,
|
||||
Veo3TextToVideoArgs,
|
||||
Veo3TextToVideoArgs, Veo3TextToVideoRequest,
|
||||
};
|
||||
|
||||
fn to_i2v_duration(d: FalVeo3Duration) -> Veo3I2vDuration {
|
||||
@@ -74,13 +74,15 @@ pub async fn execute_fal_veo_3(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalVeo3Mode::TextToVideo => {
|
||||
let args = Veo3TextToVideoArgs {
|
||||
prompt: plan.prompt.as_str(),
|
||||
negative_prompt: plan.negative_prompt.as_deref(),
|
||||
request: Veo3TextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
duration: to_t2v_duration(plan.duration),
|
||||
aspect_ratio: plan.t2v_aspect_ratio.map(to_t2v_aspect_ratio).unwrap_or(Veo3T2vAspectRatio::Default),
|
||||
resolution: to_t2v_resolution(plan.resolution),
|
||||
generate_audio: plan.generate_audio,
|
||||
},
|
||||
api_key: &fal_client.api_key,
|
||||
duration: to_t2v_duration(plan.duration),
|
||||
aspect_ratio: plan.t2v_aspect_ratio.map(to_t2v_aspect_ratio).unwrap_or(Veo3T2vAspectRatio::Default),
|
||||
resolution: to_t2v_resolution(plan.resolution),
|
||||
generate_audio: plan.generate_audio,
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
};
|
||||
enqueue_veo_3_text_to_video_webhook(args)
|
||||
|
||||
+13
-11
@@ -22,8 +22,8 @@ use fal_client::requests::webhook::video::image::enqueue_veo_3p1_image_to_video_
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{
|
||||
enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs,
|
||||
EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds,
|
||||
EnqueueVeo3p1TextToVideoResolution,
|
||||
EnqueueVeo3p1TextToVideoRequest, EnqueueVeo3p1TextToVideoAspectRatio,
|
||||
EnqueueVeo3p1TextToVideoDurationSeconds, EnqueueVeo3p1TextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3p1(
|
||||
@@ -33,15 +33,17 @@ pub async fn execute_fal_veo_3p1(
|
||||
let webhook_response = match &plan.mode {
|
||||
FalVeo3p1Mode::TextToVideo => {
|
||||
let args = EnqueueVeo3p1TextToVideoArgs {
|
||||
prompt: plan.prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
generate_audio: plan.generate_audio,
|
||||
enhance_prompt: None,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
request: EnqueueVeo3p1TextToVideoRequest {
|
||||
prompt: plan.prompt.clone(),
|
||||
duration: plan.duration.map(to_t2v_duration),
|
||||
aspect_ratio: plan.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
resolution: plan.resolution.map(to_t2v_resolution),
|
||||
generate_audio: plan.generate_audio,
|
||||
enhance_prompt: None,
|
||||
negative_prompt: plan.negative_prompt.clone(),
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+13
-11
@@ -23,8 +23,8 @@ use fal_client::requests::webhook::video::image::enqueue_veo_3p1_fast_image_to_v
|
||||
};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_fast_text_to_video_webhook::{
|
||||
enqueue_veo_3p1_fast_text_to_video_webhook, EnqueueVeo3p1FastTextToVideoArgs,
|
||||
EnqueueVeo3p1FastTextToVideoAspectRatio, EnqueueVeo3p1FastTextToVideoDurationSeconds,
|
||||
EnqueueVeo3p1FastTextToVideoResolution,
|
||||
EnqueueVeo3p1FastTextToVideoRequest, EnqueueVeo3p1FastTextToVideoAspectRatio,
|
||||
EnqueueVeo3p1FastTextToVideoDurationSeconds, EnqueueVeo3p1FastTextToVideoResolution,
|
||||
};
|
||||
|
||||
pub async fn execute_fal_veo_3p1_fast(
|
||||
@@ -36,15 +36,17 @@ pub async fn execute_fal_veo_3p1_fast(
|
||||
let webhook_response = match &inner.mode {
|
||||
FalVeo3p1Mode::TextToVideo => {
|
||||
let args = EnqueueVeo3p1FastTextToVideoArgs {
|
||||
prompt: inner.prompt.clone(),
|
||||
duration: inner.duration.map(to_t2v_duration),
|
||||
aspect_ratio: inner.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
resolution: inner.resolution.map(to_t2v_resolution),
|
||||
generate_audio: inner.generate_audio,
|
||||
enhance_prompt: None,
|
||||
negative_prompt: inner.negative_prompt.clone(),
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
request: EnqueueVeo3p1FastTextToVideoRequest {
|
||||
prompt: inner.prompt.clone(),
|
||||
duration: inner.duration.map(to_t2v_duration),
|
||||
aspect_ratio: inner.aspect_ratio.map(to_t2v_aspect_ratio),
|
||||
resolution: inner.resolution.map(to_t2v_resolution),
|
||||
generate_audio: inner.generate_audio,
|
||||
enhance_prompt: None,
|
||||
negative_prompt: inner.negative_prompt.clone(),
|
||||
seed: None,
|
||||
auto_fix: None,
|
||||
},
|
||||
webhook_url: fal_client.webhook_url.as_str(),
|
||||
api_key: &fal_client.api_key,
|
||||
};
|
||||
|
||||
+16
-10
@@ -7,18 +7,21 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueHailuoV2p3ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueHailuoV2p3ProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueHailuoV2p3ProTextToVideoRequest {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
|
||||
// Optional args
|
||||
pub prompt_optimizer: Option<bool>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueHailuoV2p3ProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueHailuoV2p3ProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
/// "Your request will cost $0.49 per video generation."
|
||||
49
|
||||
@@ -32,10 +35,11 @@ pub async fn enqueue_hailuo_v2p3_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueHailuoV2p3ProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let prompt_optimizer = args.prompt_optimizer.unwrap_or(true);
|
||||
let req = args.request;
|
||||
let prompt_optimizer = req.prompt_optimizer.unwrap_or(true);
|
||||
|
||||
let request = HailuoV2p3ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
prompt_optimizer: Some(prompt_optimizer),
|
||||
};
|
||||
@@ -51,7 +55,7 @@ pub async fn enqueue_hailuo_v2p3_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_hailuo_v2p3_pro_text_to_video_webhook::{enqueue_hailuo_v2p3_pro_text_to_video_webhook, EnqueueHailuoV2p3ProTextToVideoArgs};
|
||||
use crate::requests::webhook::video::text::enqueue_hailuo_v2p3_pro_text_to_video_webhook::{enqueue_hailuo_v2p3_pro_text_to_video_webhook, EnqueueHailuoV2p3ProTextToVideoArgs, EnqueueHailuoV2p3ProTextToVideoRequest};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -64,8 +68,10 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueHailuoV2p3ProTextToVideoArgs {
|
||||
prompt: "a gray alien with big eyes dressed in an american flag tank top gives the peace symbol, it then barbecues some hot dogs on the grill".to_string(),
|
||||
prompt_optimizer: Some(true),
|
||||
request: EnqueueHailuoV2p3ProTextToVideoRequest {
|
||||
prompt: "a gray alien with big eyes dressed in an american flag tank top gives the peace symbol, it then barbecues some hot dogs on the grill".to_string(),
|
||||
prompt_optimizer: Some(true),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+63
-54
@@ -7,6 +7,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKling3p0ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueKling3p0ProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueKling3p0ProTextToVideoRequest {
|
||||
pub prompt: String,
|
||||
|
||||
// Optional args
|
||||
@@ -15,10 +22,6 @@ pub struct EnqueueKling3p0ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub duration: Option<EnqueueKling3p0ProTextToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0ProTextToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0ProTextToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
@@ -89,7 +92,7 @@ pub enum EnqueueKling3p0ProTextToVideoShotType {
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0ProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueKling3p0ProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Kling 3.0 Pro pricing:
|
||||
// Audio off: $0.224/second
|
||||
@@ -110,10 +113,12 @@ pub async fn enqueue_kling_3p0_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueKling3p0ProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|d| d.to_str().to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect| match aspect {
|
||||
EnqueueKling3p0ProTextToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -121,7 +126,7 @@ pub async fn enqueue_kling_3p0_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
let shot_type = req.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0ProTextToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0ProTextToVideoShotType::Intelligent => "intelligent",
|
||||
@@ -129,11 +134,11 @@ pub async fn enqueue_kling_3p0_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
prompt: req.prompt,
|
||||
generate_audio: req.generate_audio,
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
negative_prompt: req.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
@@ -157,49 +162,45 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_cost() {
|
||||
let api_key = FalApiKey::from_str("");
|
||||
|
||||
let mut args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
let mut req = EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: "a spacecraft drifts through an asteroid field, dramatic lighting".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
// Audio off: $0.224/sec
|
||||
// 5s: (224 * 5 + 9) / 10 = 1129 / 10 = 112
|
||||
assert_eq!(args.calculate_cost_in_cents(), 112);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 112);
|
||||
|
||||
// 3s: (224 * 3 + 9) / 10 = 681 / 10 = 68
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 68);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 68);
|
||||
|
||||
// 10s: (224 * 10 + 9) / 10 = 2249 / 10 = 224
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 224);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 224);
|
||||
|
||||
// 15s: (224 * 15 + 9) / 10 = 3369 / 10 = 336
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 336);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 336);
|
||||
|
||||
// Audio on: $0.336/sec
|
||||
args.generate_audio = Some(true);
|
||||
req.generate_audio = Some(true);
|
||||
|
||||
// 5s: (336 * 5 + 9) / 10 = 1689 / 10 = 168
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 168);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 168);
|
||||
|
||||
// 10s: (336 * 10 + 9) / 10 = 3369 / 10 = 336
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 336);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 336);
|
||||
|
||||
// 15s: (336 * 15 + 9) / 10 = 5049 / 10 = 504
|
||||
args.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 504);
|
||||
req.duration = Some(EnqueueKling3p0ProTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 504);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -209,12 +210,14 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
prompt: "a samurai draws a katana in a bamboo forest, cherry blossoms falling in slow motion".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: "a samurai draws a katana in a bamboo forest, cherry blossoms falling in slow motion".to_string(),
|
||||
generate_audio: Some(true),
|
||||
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",
|
||||
};
|
||||
@@ -234,12 +237,14 @@ mod tests {
|
||||
for ar in EnqueueKling3p0ProTextToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
prompt: "a lighthouse beam sweeps across a stormy sea at night".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: "a lighthouse beam sweeps across a stormy sea at night".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0ProTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -259,12 +264,14 @@ mod tests {
|
||||
for dur in EnqueueKling3p0ProTextToVideoDuration::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
prompt: "a hot air balloon rises over misty mountains at dawn".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: "a hot air balloon rises over misty mountains at dawn".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0ProTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -284,12 +291,14 @@ mod tests {
|
||||
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),
|
||||
request: EnqueueKling3p0ProTextToVideoRequest {
|
||||
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",
|
||||
};
|
||||
|
||||
+63
-54
@@ -7,6 +7,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKling3p0StandardTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueKling3p0StandardTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueKling3p0StandardTextToVideoRequest {
|
||||
pub prompt: String,
|
||||
|
||||
// Optional args
|
||||
@@ -15,10 +22,6 @@ pub struct EnqueueKling3p0StandardTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub duration: Option<EnqueueKling3p0StandardTextToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueKling3p0StandardTextToVideoAspectRatio>,
|
||||
pub shot_type: Option<EnqueueKling3p0StandardTextToVideoShotType>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
@@ -89,7 +92,7 @@ pub enum EnqueueKling3p0StandardTextToVideoShotType {
|
||||
Intelligent,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKling3p0StandardTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueKling3p0StandardTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Kling 3.0 Standard pricing:
|
||||
// Audio off: $0.168/second
|
||||
@@ -111,10 +114,12 @@ pub async fn enqueue_kling_3p0_standard_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueKling3p0StandardTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|d| d.to_str().to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect| match aspect {
|
||||
EnqueueKling3p0StandardTextToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -122,7 +127,7 @@ pub async fn enqueue_kling_3p0_standard_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let shot_type = args.shot_type
|
||||
let shot_type = req.shot_type
|
||||
.map(|st| match st {
|
||||
EnqueueKling3p0StandardTextToVideoShotType::Customize => "customize",
|
||||
EnqueueKling3p0StandardTextToVideoShotType::Intelligent => "intelligent",
|
||||
@@ -130,11 +135,11 @@ pub async fn enqueue_kling_3p0_standard_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Kling3p0StandardTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
prompt: req.prompt,
|
||||
generate_audio: req.generate_audio,
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
negative_prompt: req.negative_prompt,
|
||||
shot_type,
|
||||
cfg_scale: None,
|
||||
};
|
||||
@@ -158,49 +163,45 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_cost() {
|
||||
let api_key = FalApiKey::from_str("");
|
||||
|
||||
let mut args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
let mut req = EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: "a cat sitting on a windowsill watching rain".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: None,
|
||||
shot_type: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
api_key: &api_key,
|
||||
};
|
||||
|
||||
// Audio off: $0.168/sec
|
||||
// 5s: (168 * 5 + 9) / 10 = 849 / 10 = 84
|
||||
assert_eq!(args.calculate_cost_in_cents(), 84);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 84);
|
||||
|
||||
// 3s: (168 * 3 + 9) / 10 = 513 / 10 = 51
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 51);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 51);
|
||||
|
||||
// 10s: (168 * 10 + 9) / 10 = 1689 / 10 = 168
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 168);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 168);
|
||||
|
||||
// 15s: (168 * 15 + 9) / 10 = 2529 / 10 = 252
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 252);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 252);
|
||||
|
||||
// Audio on: $0.252/sec
|
||||
args.generate_audio = Some(true);
|
||||
req.generate_audio = Some(true);
|
||||
|
||||
// 5s: (252 * 5 + 9) / 10 = 1269 / 10 = 126
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 126);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 126);
|
||||
|
||||
// 10s: (252 * 10 + 9) / 10 = 2529 / 10 = 252
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 252);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::TenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 252);
|
||||
|
||||
// 15s: (252 * 15 + 9) / 10 = 3789 / 10 = 378
|
||||
args.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(args.calculate_cost_in_cents(), 378);
|
||||
req.duration = Some(EnqueueKling3p0StandardTextToVideoDuration::FifteenSeconds);
|
||||
assert_eq!(req.calculate_cost_in_cents(), 378);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -210,12 +211,14 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
prompt: "a golden retriever puppy chases butterflies through a sunlit meadow, cinematic slow motion".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: "a golden retriever puppy chases butterflies through a sunlit meadow, cinematic slow motion".to_string(),
|
||||
generate_audio: Some(true),
|
||||
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",
|
||||
};
|
||||
@@ -235,12 +238,14 @@ mod tests {
|
||||
for ar in EnqueueKling3p0StandardTextToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
prompt: "a wave crashes against a rocky shoreline at sunset".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: "a wave crashes against a rocky shoreline at sunset".to_string(),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueueKling3p0StandardTextToVideoDuration::ThreeSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
shot_type: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -260,12 +265,14 @@ mod tests {
|
||||
for dur in EnqueueKling3p0StandardTextToVideoDuration::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
prompt: "a candle flame flickers in a dark room".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
request: EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: "a candle flame flickers in a dark room".to_string(),
|
||||
generate_audio: Some(false),
|
||||
negative_prompt: None,
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueKling3p0StandardTextToVideoAspectRatio::SixteenByNine),
|
||||
shot_type: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -285,12 +292,14 @@ mod tests {
|
||||
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),
|
||||
request: EnqueueKling3p0StandardTextToVideoRequest {
|
||||
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",
|
||||
};
|
||||
|
||||
+22
-15
@@ -7,6 +7,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKlingV2p5TurboProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueKlingV2p5TurboProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueKlingV2p5TurboProTextToVideoRequest {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
|
||||
@@ -14,10 +21,6 @@ pub struct EnqueueKlingV2p5TurboProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKlingV2p5TurboProTextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueKlingV2p5TurboProTextToVideoAspectRatio>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -34,7 +37,7 @@ pub enum EnqueueKlingV2p5TurboProTextToVideoAspectRatio {
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKlingV2p5TurboProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueKlingV2p5TurboProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// "For 5s video your request will cost $0.35.
|
||||
// For every additional second you will be charged $0.07."
|
||||
@@ -53,14 +56,16 @@ pub async fn enqueue_kling_v2p5_turbo_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueKlingV2p5TurboProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Five => "5",
|
||||
EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Ten => "10",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect| match aspect {
|
||||
EnqueueKlingV2p5TurboProTextToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKlingV2p5TurboProTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -69,11 +74,11 @@ pub async fn enqueue_kling_v2p5_turbo_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = KlingV2p5TurboProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
negative_prompt: req.negative_prompt,
|
||||
// Constants
|
||||
cfg_scale: None,
|
||||
};
|
||||
@@ -89,7 +94,7 @@ pub async fn enqueue_kling_v2p5_turbo_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs, EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds};
|
||||
use crate::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs, EnqueueKlingV2p5TurboProTextToVideoRequest, EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -102,10 +107,12 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueKlingV2p5TurboProTextToVideoArgs {
|
||||
prompt: "an owl flies by an abandoned castle at dusk. the camera tracks the flying owl. the castle stones are damp and gritty. there are lots of trees. fireflies dance over the fields".to_string(),
|
||||
negative_prompt: None,
|
||||
aspect_ratio: Some(EnqueueKlingV2p5TurboProTextToVideoAspectRatio::SixteenByNine),
|
||||
duration: Some(EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Five),
|
||||
request: EnqueueKlingV2p5TurboProTextToVideoRequest {
|
||||
prompt: "an owl flies by an abandoned castle at dusk. the camera tracks the flying owl. the castle stones are damp and gritty. there are lots of trees. fireflies dance over the fields".to_string(),
|
||||
negative_prompt: None,
|
||||
aspect_ratio: Some(EnqueueKlingV2p5TurboProTextToVideoAspectRatio::SixteenByNine),
|
||||
duration: Some(EnqueueKlingV2p5TurboProTextToVideoDurationSeconds::Five),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+24
-17
@@ -7,6 +7,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueKlingV2p6ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueKlingV2p6ProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueKlingV2p6ProTextToVideoRequest {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
|
||||
@@ -15,10 +22,6 @@ pub struct EnqueueKlingV2p6ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Option<EnqueueKlingV2p6ProTextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueKlingV2p6ProTextToVideoAspectRatio>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -34,7 +37,7 @@ pub enum EnqueueKlingV2p6ProTextToVideoAspectRatio {
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueKlingV2p6ProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueKlingV2p6ProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// "For every second of video you generated, you will be
|
||||
// charged $0.07 (audio off) or $0.14 (audio on).
|
||||
@@ -58,14 +61,16 @@ pub async fn enqueue_kling_v2p6_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueKlingV2p6ProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueKlingV2p6ProTextToVideoDurationSeconds::Five => "5",
|
||||
EnqueueKlingV2p6ProTextToVideoDurationSeconds::Ten => "10",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect| match aspect {
|
||||
EnqueueKlingV2p6ProTextToVideoAspectRatio::Square => "1:1",
|
||||
EnqueueKlingV2p6ProTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -74,12 +79,12 @@ pub async fn enqueue_kling_v2p6_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = KlingV2p6ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
generate_audio: args.generate_audio,
|
||||
generate_audio: req.generate_audio,
|
||||
duration,
|
||||
aspect_ratio,
|
||||
negative_prompt: args.negative_prompt,
|
||||
negative_prompt: req.negative_prompt,
|
||||
// Constants
|
||||
cfg_scale: None,
|
||||
};
|
||||
@@ -95,7 +100,7 @@ pub async fn enqueue_kling_v2p6_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs, EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds};
|
||||
use crate::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs, EnqueueKlingV2p6ProTextToVideoRequest, EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -108,11 +113,13 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueKlingV2p6ProTextToVideoArgs {
|
||||
prompt: "a humanoid lizard creature walks around on the surface of an alien planet. the sky is purple and there are yellow plants. The lizard says, 'You should consider day trading'. Suddenly a giant t-rex comes in from off screen and eats the lizard creature.".to_string(),
|
||||
negative_prompt: None,
|
||||
aspect_ratio: Some(EnqueueKlingV2p6ProTextToVideoAspectRatio::SixteenByNine),
|
||||
duration: Some(EnqueueKlingV2p6ProTextToVideoDurationSeconds::Ten),
|
||||
generate_audio: Some(true),
|
||||
request: EnqueueKlingV2p6ProTextToVideoRequest {
|
||||
prompt: "a humanoid lizard creature walks around on the surface of an alien planet. the sky is purple and there are yellow plants. The lizard says, 'You should consider day trading'. Suddenly a giant t-rex comes in from off screen and eats the lizard creature.".to_string(),
|
||||
negative_prompt: None,
|
||||
aspect_ratio: Some(EnqueueKlingV2p6ProTextToVideoAspectRatio::SixteenByNine),
|
||||
duration: Some(EnqueueKlingV2p6ProTextToVideoDurationSeconds::Ten),
|
||||
generate_audio: Some(true),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+24
-17
@@ -6,6 +6,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueuePixverseV5TextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueuePixverseV5TextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueuePixverseV5TextToVideoRequest {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
|
||||
@@ -17,10 +24,6 @@ pub struct EnqueuePixverseV5TextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub aspect_ratio: Option<EnqueuePixverseV5TextToVideoAspectRatio>,
|
||||
pub resolution: Option<EnqueuePixverseV5TextToVideoResolution>,
|
||||
pub style: Option<EnqueuePixverseV5TextToVideoStyle>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -59,14 +62,16 @@ pub async fn enqueue_pixverse_v5_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueuePixverseV5TextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|resolution| match resolution {
|
||||
EnqueuePixverseV5TextToVideoDurationSeconds::Five => "5",
|
||||
EnqueuePixverseV5TextToVideoDurationSeconds::Eight=> "8",
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect_ratio| match aspect_ratio {
|
||||
EnqueuePixverseV5TextToVideoAspectRatio::Square => "1:1",
|
||||
EnqueuePixverseV5TextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -76,7 +81,7 @@ pub async fn enqueue_pixverse_v5_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|resolution| match resolution {
|
||||
EnqueuePixverseV5TextToVideoResolution::ThreeSixtyP => "360p",
|
||||
EnqueuePixverseV5TextToVideoResolution::FiveFortyP => "540p",
|
||||
@@ -85,7 +90,7 @@ pub async fn enqueue_pixverse_v5_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let style = args.style
|
||||
let style = req.style
|
||||
.map(|style| match style {
|
||||
EnqueuePixverseV5TextToVideoStyle::Anime => "anime",
|
||||
EnqueuePixverseV5TextToVideoStyle::Animation3d => "3d_animation",
|
||||
@@ -96,10 +101,10 @@ pub async fn enqueue_pixverse_v5_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = PixverseV5TextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
duration,
|
||||
negative_prompt: args.negative_prompt,
|
||||
negative_prompt: req.negative_prompt,
|
||||
aspect_ratio,
|
||||
resolution,
|
||||
style,
|
||||
@@ -118,7 +123,7 @@ pub async fn enqueue_pixverse_v5_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_pixverse_v5_text_to_video_webhook::{enqueue_pixverse_v5_text_to_video_webhook, EnqueuePixverseV5TextToVideoArgs, EnqueuePixverseV5TextToVideoAspectRatio, EnqueuePixverseV5TextToVideoDurationSeconds, EnqueuePixverseV5TextToVideoResolution, EnqueuePixverseV5TextToVideoStyle};
|
||||
use crate::requests::webhook::video::text::enqueue_pixverse_v5_text_to_video_webhook::{enqueue_pixverse_v5_text_to_video_webhook, EnqueuePixverseV5TextToVideoArgs, EnqueuePixverseV5TextToVideoRequest, EnqueuePixverseV5TextToVideoAspectRatio, EnqueuePixverseV5TextToVideoDurationSeconds, EnqueuePixverseV5TextToVideoResolution, EnqueuePixverseV5TextToVideoStyle};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -131,12 +136,14 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueuePixverseV5TextToVideoArgs {
|
||||
prompt: "an angry racoon shakes its fist at the garbage truck as it drives away, the camera orbits the racoon. the racoon sighs".to_string(),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueuePixverseV5TextToVideoDurationSeconds::Eight),
|
||||
style: Some(EnqueuePixverseV5TextToVideoStyle::Anime),
|
||||
aspect_ratio: Some(EnqueuePixverseV5TextToVideoAspectRatio::FourByThree),
|
||||
resolution: Some(EnqueuePixverseV5TextToVideoResolution::SevenTwentyP),
|
||||
request: EnqueuePixverseV5TextToVideoRequest {
|
||||
prompt: "an angry racoon shakes its fist at the garbage truck as it drives away, the camera orbits the racoon. the racoon sighs".to_string(),
|
||||
negative_prompt: None,
|
||||
duration: Some(EnqueuePixverseV5TextToVideoDurationSeconds::Eight),
|
||||
style: Some(EnqueuePixverseV5TextToVideoStyle::Anime),
|
||||
aspect_ratio: Some(EnqueuePixverseV5TextToVideoAspectRatio::FourByThree),
|
||||
resolution: Some(EnqueuePixverseV5TextToVideoResolution::SevenTwentyP),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+65
-60
@@ -7,6 +7,13 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueSeedance1p5ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub request: EnqueueSeedance1p5ProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
|
||||
@@ -15,10 +22,6 @@ pub struct EnqueueSeedance1p5ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub duration: Option<EnqueueSeedance1p5ProTextToVideoDuration>,
|
||||
pub aspect_ratio: Option<EnqueueSeedance1p5ProTextToVideoAspectRatio>,
|
||||
pub generate_audio: Option<bool>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, strum::EnumIter)]
|
||||
@@ -52,7 +55,7 @@ pub enum EnqueueSeedance1p5ProTextToVideoAspectRatio {
|
||||
Auto,
|
||||
}
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueSeedance1p5ProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Fal:
|
||||
// "Each 720p 5 second video with audio costs roughly $0.26.
|
||||
@@ -110,7 +113,9 @@ pub async fn enqueue_seedance_1p5_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueSeedance1p5ProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
|
||||
let duration = args.duration
|
||||
let req = args.request;
|
||||
|
||||
let duration = req.duration
|
||||
.map(|d| match d {
|
||||
EnqueueSeedance1p5ProTextToVideoDuration::FourSeconds => "4",
|
||||
EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds => "5",
|
||||
@@ -124,7 +129,7 @@ pub async fn enqueue_seedance_1p5_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|d| d.to_string());
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|r| match r {
|
||||
EnqueueSeedance1p5ProTextToVideoResolution::FourEightyP => "480p",
|
||||
EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP => "720p",
|
||||
@@ -132,7 +137,7 @@ pub async fn enqueue_seedance_1p5_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|r| r.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|ar| match ar {
|
||||
EnqueueSeedance1p5ProTextToVideoAspectRatio::TwentyOneByNine => "21:9",
|
||||
EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -145,14 +150,14 @@ pub async fn enqueue_seedance_1p5_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|ar| ar.to_string());
|
||||
|
||||
let request = Seedance1p5ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
duration,
|
||||
resolution,
|
||||
aspect_ratio,
|
||||
camera_fixed: None,
|
||||
seed: None,
|
||||
enable_safety_checker: Some(false),
|
||||
generate_audio: Some(args.generate_audio.unwrap_or(true)),
|
||||
generate_audio: Some(req.generate_audio.unwrap_or(true)),
|
||||
};
|
||||
|
||||
let result = seedance_1p5_pro_text_to_video(request)
|
||||
@@ -174,71 +179,63 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_cost() {
|
||||
let api_key = FalApiKey::from_str("");
|
||||
|
||||
let mut args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
let mut req = EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
api_key: &api_key,
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds),
|
||||
resolution: Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP),
|
||||
aspect_ratio: None,
|
||||
generate_audio: None,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
// NB: Constant value specified by Fal
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 26);
|
||||
|
||||
// Calculated values
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 65);
|
||||
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 73);
|
||||
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 146);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cost_audio_off() {
|
||||
let api_key = FalApiKey::from_str("");
|
||||
|
||||
let mut args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
let mut req = EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: String::new(),
|
||||
api_key: &api_key,
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds),
|
||||
resolution: Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP),
|
||||
aspect_ratio: None,
|
||||
generate_audio: Some(false),
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
// 720p 5s without audio = half of 26
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 13);
|
||||
|
||||
// Calculated values — half of audio-on costs (ceil)
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 33);
|
||||
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 37);
|
||||
|
||||
args.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
args.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
req.duration = Some(EnqueueSeedance1p5ProTextToVideoDuration::TenSeconds);
|
||||
req.resolution = Some(EnqueueSeedance1p5ProTextToVideoResolution::TenEightyP);
|
||||
let cost = req.calculate_cost_in_cents();
|
||||
assert_eq!(cost, 73);
|
||||
}
|
||||
|
||||
@@ -249,11 +246,13 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: "a dinosaur walks through a misty forest at dawn, cinematic lighting".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP),
|
||||
generate_audio: None,
|
||||
request: EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: "a dinosaur walks through a misty forest at dawn, cinematic lighting".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FiveSeconds),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueSeedance1p5ProTextToVideoResolution::SevenTwentyP),
|
||||
generate_audio: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -273,11 +272,13 @@ mod tests {
|
||||
for ar in EnqueueSeedance1p5ProTextToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: "a corgi runs along a beach at golden hour".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FourSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
generate_audio: None,
|
||||
request: EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: "a corgi runs along a beach at golden hour".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FourSeconds),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
generate_audio: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -297,11 +298,13 @@ mod tests {
|
||||
for dur in EnqueueSeedance1p5ProTextToVideoDuration::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: "a corgi runs along a beach at golden hour".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
generate_audio: None,
|
||||
request: EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: "a corgi runs along a beach at golden hour".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
generate_audio: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -321,11 +324,13 @@ mod tests {
|
||||
for res in EnqueueSeedance1p5ProTextToVideoResolution::iter() {
|
||||
println!("--- resolution: {:?} ---", res);
|
||||
let args = EnqueueSeedance1p5ProTextToVideoArgs {
|
||||
prompt: "a bird flying over an ocean at golden hour".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FourSeconds),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(res),
|
||||
generate_audio: None,
|
||||
request: EnqueueSeedance1p5ProTextToVideoRequest {
|
||||
prompt: "a bird flying over an ocean at golden hour".to_string(),
|
||||
duration: Some(EnqueueSeedance1p5ProTextToVideoDuration::FourSeconds),
|
||||
aspect_ratio: Some(EnqueueSeedance1p5ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(res),
|
||||
generate_audio: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+37
-28
@@ -7,17 +7,17 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueSora2ProTextToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub request: EnqueueSora2ProTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
// Optional args
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueSora2ProTextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub resolution: Option<EnqueueSora2ProTextToVideoResolution>,
|
||||
pub duration: Option<EnqueueSora2ProTextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueSora2ProTextToVideoAspectRatio>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, strum::EnumIter)]
|
||||
@@ -40,7 +40,7 @@ pub enum EnqueueSora2ProTextToVideoAspectRatio {
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueSora2ProTextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueSora2ProTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Pricing: $0.30/s for 720p and $0.50/s for 1080p.
|
||||
let duration = self.duration.unwrap_or(EnqueueSora2ProTextToVideoDurationSeconds::Four);
|
||||
@@ -62,22 +62,23 @@ impl <U: IntoUrl> FalRequestCostCalculator for EnqueueSora2ProTextToVideoArgs<'_
|
||||
pub async fn enqueue_sora_2_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueSora2ProTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let req = args.request;
|
||||
|
||||
let duration = args.duration
|
||||
let duration = req.duration
|
||||
.map(|d| match d {
|
||||
EnqueueSora2ProTextToVideoDurationSeconds::Four => 4,
|
||||
EnqueueSora2ProTextToVideoDurationSeconds::Eight => 8,
|
||||
EnqueueSora2ProTextToVideoDurationSeconds::Twelve => 12,
|
||||
});
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|r| match r {
|
||||
EnqueueSora2ProTextToVideoResolution::SevenTwentyP => "720p",
|
||||
EnqueueSora2ProTextToVideoResolution::TenEightyP => "1080p",
|
||||
})
|
||||
.map(|r| r.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|ar| match ar {
|
||||
EnqueueSora2ProTextToVideoAspectRatio::NineBySixteen => "9:16",
|
||||
EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -85,7 +86,7 @@ pub async fn enqueue_sora_2_pro_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|ar| ar.to_string());
|
||||
|
||||
let request = Sora2ProTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
duration,
|
||||
resolution,
|
||||
aspect_ratio,
|
||||
@@ -115,10 +116,12 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
prompt: "a dinosaur turns to the camera and asks, 'do you have adequate car insurance?' it then stomps off and attacks a brontosaurus".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::NineBySixteen),
|
||||
resolution: Some(EnqueueSora2ProTextToVideoResolution::SevenTwentyP),
|
||||
request: EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: "a dinosaur turns to the camera and asks, 'do you have adequate car insurance?' it then stomps off and attacks a brontosaurus".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::NineBySixteen),
|
||||
resolution: Some(EnqueueSora2ProTextToVideoResolution::SevenTwentyP),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -138,10 +141,12 @@ mod tests {
|
||||
for ar in EnqueueSora2ProTextToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
prompt: "a serene mountain lake at sunset with gentle ripples".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
request: EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: "a serene mountain lake at sunset with gentle ripples".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -161,10 +166,12 @@ mod tests {
|
||||
for dur in EnqueueSora2ProTextToVideoDurationSeconds::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
prompt: "Suspenseful Hollywood movie. Interior, night. Customers are eating at a city diner. Suddenly a t-rex bursts its head through the large windows. The customers run.".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
request: EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: "Suspenseful Hollywood movie. Interior, night. Customers are eating at a city diner. Suddenly a t-rex bursts its head through the large windows. The customers run.".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -184,10 +191,12 @@ mod tests {
|
||||
for res in EnqueueSora2ProTextToVideoResolution::iter() {
|
||||
println!("--- resolution: {:?} ---", res);
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
prompt: "a bird flying over an ocean at golden hour".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(res),
|
||||
request: EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: "a bird flying over an ocean at golden hour".to_string(),
|
||||
duration: Some(EnqueueSora2ProTextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(EnqueueSora2ProTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(res),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+31
-24
@@ -7,17 +7,17 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueSora2TextToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub request: EnqueueSora2TextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
// Optional args
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueSora2TextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub resolution: Option<EnqueueSora2TextToVideoResolution>,
|
||||
pub duration: Option<EnqueueSora2TextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueSora2TextToVideoAspectRatio>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, strum::EnumIter)]
|
||||
@@ -39,7 +39,7 @@ pub enum EnqueueSora2TextToVideoAspectRatio {
|
||||
}
|
||||
|
||||
|
||||
impl <U: IntoUrl> FalRequestCostCalculator for EnqueueSora2TextToVideoArgs<'_, U> {
|
||||
impl FalRequestCostCalculator for EnqueueSora2TextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// "The pricing is $0.1/s for Sora 2."
|
||||
let duration = self.duration.unwrap_or(EnqueueSora2TextToVideoDurationSeconds::Four);
|
||||
@@ -56,21 +56,22 @@ impl <U: IntoUrl> FalRequestCostCalculator for EnqueueSora2TextToVideoArgs<'_, U
|
||||
pub async fn enqueue_sora_2_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueSora2TextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let req = args.request;
|
||||
|
||||
let duration = args.duration
|
||||
let duration = req.duration
|
||||
.map(|d| match d {
|
||||
EnqueueSora2TextToVideoDurationSeconds::Four => 4,
|
||||
EnqueueSora2TextToVideoDurationSeconds::Eight => 8,
|
||||
EnqueueSora2TextToVideoDurationSeconds::Twelve => 12,
|
||||
});
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|r| match r {
|
||||
EnqueueSora2TextToVideoResolution::SevenTwentyP => "720p",
|
||||
})
|
||||
.map(|r| r.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|ar| match ar {
|
||||
EnqueueSora2TextToVideoAspectRatio::NineBySixteen => "9:16",
|
||||
EnqueueSora2TextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -78,7 +79,7 @@ pub async fn enqueue_sora_2_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|ar| ar.to_string());
|
||||
|
||||
let request = Sora2TextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
duration,
|
||||
resolution,
|
||||
aspect_ratio,
|
||||
@@ -108,10 +109,12 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
prompt: "a dinosaur turns to the camera and asks, 'do you have adequate car insurance?' it then stomps off and attacks a brontosaurus".to_string(),
|
||||
duration: Some(EnqueueSora2TextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueSora2TextToVideoAspectRatio::NineBySixteen),
|
||||
resolution: Some(EnqueueSora2TextToVideoResolution::SevenTwentyP),
|
||||
request: EnqueueSora2TextToVideoRequest {
|
||||
prompt: "a dinosaur turns to the camera and asks, 'do you have adequate car insurance?' it then stomps off and attacks a brontosaurus".to_string(),
|
||||
duration: Some(EnqueueSora2TextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueSora2TextToVideoAspectRatio::NineBySixteen),
|
||||
resolution: Some(EnqueueSora2TextToVideoResolution::SevenTwentyP),
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -131,10 +134,12 @@ mod tests {
|
||||
for ar in EnqueueSora2TextToVideoAspectRatio::iter() {
|
||||
println!("--- aspect ratio: {:?} ---", ar);
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
prompt: "a snowy mountain cabin at sunrise".to_string(),
|
||||
duration: Some(EnqueueSora2TextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
request: EnqueueSora2TextToVideoRequest {
|
||||
prompt: "a snowy mountain cabin at sunrise".to_string(),
|
||||
duration: Some(EnqueueSora2TextToVideoDurationSeconds::Four),
|
||||
aspect_ratio: Some(ar),
|
||||
resolution: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
@@ -154,10 +159,12 @@ mod tests {
|
||||
for dur in EnqueueSora2TextToVideoDurationSeconds::iter() {
|
||||
println!("--- duration: {:?} ---", dur);
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
prompt: "a corgi walks in front of a giant windmill in a beautiful village at sunrise".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSora2TextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
request: EnqueueSora2TextToVideoRequest {
|
||||
prompt: "a corgi walks in front of a giant windmill in a beautiful village at sunrise".to_string(),
|
||||
duration: Some(dur),
|
||||
aspect_ratio: Some(EnqueueSora2TextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+24
-14
@@ -15,15 +15,20 @@ pub use crate::requests::webhook::video::image::enqueue_veo_2_image_to_video_web
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct Veo2TextToVideoArgs<'a, V: IntoUrl> {
|
||||
pub prompt: &'a str,
|
||||
pub negative_prompt: Option<&'a str>,
|
||||
pub duration: Veo2Duration,
|
||||
pub aspect_ratio: Veo2AspectRatio,
|
||||
pub request: Veo2TextToVideoRequest,
|
||||
pub webhook_url: V,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
impl<V: IntoUrl> FalRequestCostCalculator for Veo2TextToVideoArgs<'_, V> {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Veo2TextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Veo2Duration,
|
||||
pub aspect_ratio: Veo2AspectRatio,
|
||||
}
|
||||
|
||||
impl FalRequestCostCalculator for Veo2TextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// Same pricing as image-to-video:
|
||||
// "For 5s video your request will cost $2.50.
|
||||
@@ -43,7 +48,9 @@ impl<V: IntoUrl> FalRequestCostCalculator for Veo2TextToVideoArgs<'_, V> {
|
||||
pub async fn enqueue_veo_2_text_to_video_webhook<V: IntoUrl>(
|
||||
args: Veo2TextToVideoArgs<'_, V>,
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let duration = match args.duration {
|
||||
let req = args.request;
|
||||
|
||||
let duration = match req.duration {
|
||||
Veo2Duration::Default => None,
|
||||
Veo2Duration::FiveSeconds => Some("5s".to_string()),
|
||||
Veo2Duration::SixSeconds => Some("6s".to_string()),
|
||||
@@ -51,7 +58,7 @@ pub async fn enqueue_veo_2_text_to_video_webhook<V: IntoUrl>(
|
||||
Veo2Duration::EightSeconds => Some("8s".to_string()),
|
||||
};
|
||||
|
||||
let aspect_ratio = match args.aspect_ratio {
|
||||
let aspect_ratio = match req.aspect_ratio {
|
||||
Veo2AspectRatio::Auto => None, // Let the API default (16:9)
|
||||
Veo2AspectRatio::AutoPreferPortrait => Some("9:16".to_string()),
|
||||
Veo2AspectRatio::WideSixteenNine => Some("16:9".to_string()),
|
||||
@@ -59,10 +66,10 @@ pub async fn enqueue_veo_2_text_to_video_webhook<V: IntoUrl>(
|
||||
};
|
||||
|
||||
let request = Veo2TextToVideoInput {
|
||||
prompt: args.prompt.to_string(),
|
||||
prompt: req.prompt,
|
||||
aspect_ratio,
|
||||
duration,
|
||||
negative_prompt: args.negative_prompt.map(|s| s.to_string()),
|
||||
negative_prompt: req.negative_prompt,
|
||||
};
|
||||
|
||||
let result = veo_2_text_to_video(request)
|
||||
@@ -77,7 +84,8 @@ pub async fn enqueue_veo_2_text_to_video_webhook<V: IntoUrl>(
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_veo_2_text_to_video_webhook::{
|
||||
enqueue_veo_2_text_to_video_webhook, Veo2TextToVideoArgs, Veo2AspectRatio, Veo2Duration,
|
||||
enqueue_veo_2_text_to_video_webhook, Veo2TextToVideoArgs, Veo2TextToVideoRequest,
|
||||
Veo2AspectRatio, Veo2Duration,
|
||||
};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
@@ -89,11 +97,13 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = Veo2TextToVideoArgs {
|
||||
prompt: "a drone shot of a coastal sunset with waves crashing on rocks",
|
||||
negative_prompt: None,
|
||||
request: Veo2TextToVideoRequest {
|
||||
prompt: "a drone shot of a coastal sunset with waves crashing on rocks".to_string(),
|
||||
negative_prompt: None,
|
||||
duration: Veo2Duration::FiveSeconds,
|
||||
aspect_ratio: Veo2AspectRatio::WideSixteenNine,
|
||||
},
|
||||
api_key: &api_key,
|
||||
duration: Veo2Duration::FiveSeconds,
|
||||
aspect_ratio: Veo2AspectRatio::WideSixteenNine,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
|
||||
+28
-19
@@ -11,14 +11,19 @@ use crate::requests::traits::fal_request_cost_calculator_trait::{
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct Veo3TextToVideoArgs<'a, V: IntoUrl> {
|
||||
pub prompt: &'a str,
|
||||
pub negative_prompt: Option<&'a str>,
|
||||
pub request: Veo3TextToVideoRequest,
|
||||
pub webhook_url: V,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Veo3TextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub negative_prompt: Option<String>,
|
||||
pub duration: Veo3T2vDuration,
|
||||
pub aspect_ratio: Veo3T2vAspectRatio,
|
||||
pub resolution: Veo3T2vResolution,
|
||||
pub generate_audio: bool,
|
||||
pub webhook_url: V,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
/// Duration for Veo 3 text-to-video. Default is 8 seconds.
|
||||
@@ -47,7 +52,7 @@ pub enum Veo3T2vResolution {
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
impl<V: IntoUrl> FalRequestCostCalculator for Veo3TextToVideoArgs<'_, V> {
|
||||
impl FalRequestCostCalculator for Veo3TextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// $0.20/sec audio off, $0.40/sec audio on.
|
||||
match (self.duration, self.generate_audio) {
|
||||
@@ -68,32 +73,34 @@ impl<V: IntoUrl> FalRequestCostCalculator for Veo3TextToVideoArgs<'_, V> {
|
||||
pub async fn enqueue_veo_3_text_to_video_webhook<V: IntoUrl>(
|
||||
args: Veo3TextToVideoArgs<'_, V>,
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let duration = match args.duration {
|
||||
let req = args.request;
|
||||
|
||||
let duration = match req.duration {
|
||||
Veo3T2vDuration::Default => None,
|
||||
Veo3T2vDuration::FourSeconds => Some("4s".to_string()),
|
||||
Veo3T2vDuration::SixSeconds => Some("6s".to_string()),
|
||||
Veo3T2vDuration::EightSeconds => Some("8s".to_string()),
|
||||
};
|
||||
|
||||
let aspect_ratio = match args.aspect_ratio {
|
||||
let aspect_ratio = match req.aspect_ratio {
|
||||
Veo3T2vAspectRatio::Default => None,
|
||||
Veo3T2vAspectRatio::WideSixteenNine => Some("16:9".to_string()),
|
||||
Veo3T2vAspectRatio::TallNineSixteen => Some("9:16".to_string()),
|
||||
};
|
||||
|
||||
let resolution = match args.resolution {
|
||||
let resolution = match req.resolution {
|
||||
Veo3T2vResolution::Default => None,
|
||||
Veo3T2vResolution::SevenTwentyP => Some("720p".to_string()),
|
||||
Veo3T2vResolution::TenEightyP => Some("1080p".to_string()),
|
||||
};
|
||||
|
||||
let request = Veo3TextToVideoInput {
|
||||
prompt: args.prompt.to_string(),
|
||||
prompt: req.prompt,
|
||||
aspect_ratio,
|
||||
resolution,
|
||||
duration,
|
||||
generate_audio: Some(args.generate_audio),
|
||||
negative_prompt: args.negative_prompt.map(|s| s.to_string()),
|
||||
generate_audio: Some(req.generate_audio),
|
||||
negative_prompt: req.negative_prompt,
|
||||
};
|
||||
|
||||
let result = veo_3_text_to_video(request)
|
||||
@@ -108,8 +115,8 @@ pub async fn enqueue_veo_3_text_to_video_webhook<V: IntoUrl>(
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_veo_3_text_to_video_webhook::{
|
||||
enqueue_veo_3_text_to_video_webhook, Veo3TextToVideoArgs, Veo3T2vAspectRatio,
|
||||
Veo3T2vDuration, Veo3T2vResolution,
|
||||
enqueue_veo_3_text_to_video_webhook, Veo3TextToVideoArgs, Veo3TextToVideoRequest,
|
||||
Veo3T2vAspectRatio, Veo3T2vDuration, Veo3T2vResolution,
|
||||
};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
@@ -121,13 +128,15 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = Veo3TextToVideoArgs {
|
||||
prompt: "a drone shot of a coastal sunset with waves crashing on rocks",
|
||||
negative_prompt: None,
|
||||
request: Veo3TextToVideoRequest {
|
||||
prompt: "a drone shot of a coastal sunset with waves crashing on rocks".to_string(),
|
||||
negative_prompt: None,
|
||||
duration: Veo3T2vDuration::EightSeconds,
|
||||
aspect_ratio: Veo3T2vAspectRatio::WideSixteenNine,
|
||||
resolution: Veo3T2vResolution::TenEightyP,
|
||||
generate_audio: true,
|
||||
},
|
||||
api_key: &api_key,
|
||||
duration: Veo3T2vDuration::EightSeconds,
|
||||
aspect_ratio: Veo3T2vAspectRatio::WideSixteenNine,
|
||||
resolution: Veo3T2vResolution::TenEightyP,
|
||||
generate_audio: true,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
|
||||
+30
-27
@@ -7,10 +7,14 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueVeo3p1FastTextToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub request: EnqueueVeo3p1FastTextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
// Optional args
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueVeo3p1FastTextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub duration: Option<EnqueueVeo3p1FastTextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueVeo3p1FastTextToVideoAspectRatio>,
|
||||
pub resolution: Option<EnqueueVeo3p1FastTextToVideoResolution>,
|
||||
@@ -19,10 +23,6 @@ pub struct EnqueueVeo3p1FastTextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub seed: Option<i64>,
|
||||
pub auto_fix: Option<bool>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -45,7 +45,7 @@ pub enum EnqueueVeo3p1FastTextToVideoResolution {
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
impl <R: IntoUrl> FalRequestCostCalculator for EnqueueVeo3p1FastTextToVideoArgs<'_, R> {
|
||||
impl FalRequestCostCalculator for EnqueueVeo3p1FastTextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// "For every second of video you generated, you will be charged
|
||||
// $0.10 (audio off) or
|
||||
@@ -73,8 +73,9 @@ impl <R: IntoUrl> FalRequestCostCalculator for EnqueueVeo3p1FastTextToVideoArgs<
|
||||
pub async fn enqueue_veo_3p1_fast_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueVeo3p1FastTextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let req = args.request;
|
||||
|
||||
let duration = args.duration
|
||||
let duration = req.duration
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueVeo3p1FastTextToVideoDurationSeconds::Four => "4s",
|
||||
EnqueueVeo3p1FastTextToVideoDurationSeconds::Six => "6s",
|
||||
@@ -82,7 +83,7 @@ pub async fn enqueue_veo_3p1_fast_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect_ratio| match aspect_ratio {
|
||||
EnqueueVeo3p1FastTextToVideoAspectRatio::Auto => "auto",
|
||||
EnqueueVeo3p1FastTextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -90,7 +91,7 @@ pub async fn enqueue_veo_3p1_fast_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueVeo3p1FastTextToVideoResolution::SevenTwentyP => "720p",
|
||||
EnqueueVeo3p1FastTextToVideoResolution::TenEightyP => "1080p",
|
||||
@@ -98,16 +99,16 @@ pub async fn enqueue_veo_3p1_fast_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Veo3p1FastTextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
duration,
|
||||
aspect_ratio,
|
||||
resolution,
|
||||
negative_prompt: args.negative_prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
enhance_prompt: args.enhance_prompt,
|
||||
seed: args.seed,
|
||||
auto_fix: args.auto_fix,
|
||||
negative_prompt: req.negative_prompt,
|
||||
generate_audio: req.generate_audio,
|
||||
enhance_prompt: req.enhance_prompt,
|
||||
seed: req.seed,
|
||||
auto_fix: req.auto_fix,
|
||||
};
|
||||
|
||||
let result = veo_3p1_fast_text_to_video(request)
|
||||
@@ -121,7 +122,7 @@ pub async fn enqueue_veo_3p1_fast_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_veo_3p1_fast_text_to_video_webhook::{enqueue_veo_3p1_fast_text_to_video_webhook, EnqueueVeo3p1FastTextToVideoArgs, EnqueueVeo3p1FastTextToVideoAspectRatio, EnqueueVeo3p1FastTextToVideoDurationSeconds, EnqueueVeo3p1FastTextToVideoResolution};
|
||||
use crate::requests::webhook::video::text::enqueue_veo_3p1_fast_text_to_video_webhook::{enqueue_veo_3p1_fast_text_to_video_webhook, EnqueueVeo3p1FastTextToVideoArgs, EnqueueVeo3p1FastTextToVideoRequest, EnqueueVeo3p1FastTextToVideoAspectRatio, EnqueueVeo3p1FastTextToVideoDurationSeconds, EnqueueVeo3p1FastTextToVideoResolution};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -134,15 +135,17 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueVeo3p1FastTextToVideoArgs {
|
||||
prompt: "An alien space ship hovers over new york city. it looks ominous, ready to attack. suddenly, it drops a bunch of ping pong balls on the city".to_string(),
|
||||
duration: Some(EnqueueVeo3p1FastTextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueVeo3p1FastTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueVeo3p1FastTextToVideoResolution::TenEightyP),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
enhance_prompt: Some(true),
|
||||
auto_fix: Some(true),
|
||||
seed: None,
|
||||
request: EnqueueVeo3p1FastTextToVideoRequest {
|
||||
prompt: "An alien space ship hovers over new york city. it looks ominous, ready to attack. suddenly, it drops a bunch of ping pong balls on the city".to_string(),
|
||||
duration: Some(EnqueueVeo3p1FastTextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueVeo3p1FastTextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueVeo3p1FastTextToVideoResolution::TenEightyP),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
enhance_prompt: Some(true),
|
||||
auto_fix: Some(true),
|
||||
seed: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+30
-27
@@ -7,10 +7,14 @@ use crate::requests::api::webhook_response::WebhookResponse;
|
||||
use reqwest::IntoUrl;
|
||||
|
||||
pub struct EnqueueVeo3p1TextToVideoArgs<'a, R: IntoUrl> {
|
||||
// Request required
|
||||
pub prompt: String,
|
||||
pub request: EnqueueVeo3p1TextToVideoRequest,
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
// Optional args
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EnqueueVeo3p1TextToVideoRequest {
|
||||
pub prompt: String,
|
||||
pub duration: Option<EnqueueVeo3p1TextToVideoDurationSeconds>,
|
||||
pub aspect_ratio: Option<EnqueueVeo3p1TextToVideoAspectRatio>,
|
||||
pub resolution: Option<EnqueueVeo3p1TextToVideoResolution>,
|
||||
@@ -19,10 +23,6 @@ pub struct EnqueueVeo3p1TextToVideoArgs<'a, R: IntoUrl> {
|
||||
pub negative_prompt: Option<String>,
|
||||
pub seed: Option<i64>,
|
||||
pub auto_fix: Option<bool>,
|
||||
|
||||
// Fulfillment
|
||||
pub webhook_url: R,
|
||||
pub api_key: &'a FalApiKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@@ -46,7 +46,7 @@ pub enum EnqueueVeo3p1TextToVideoResolution {
|
||||
}
|
||||
|
||||
|
||||
impl <R: IntoUrl> FalRequestCostCalculator for EnqueueVeo3p1TextToVideoArgs<'_, R> {
|
||||
impl FalRequestCostCalculator for EnqueueVeo3p1TextToVideoRequest {
|
||||
fn calculate_cost_in_cents(&self) -> UsdCents {
|
||||
// "For every second of video you generated, you will be charged
|
||||
// $0.20 (audio off) or
|
||||
@@ -74,8 +74,9 @@ impl <R: IntoUrl> FalRequestCostCalculator for EnqueueVeo3p1TextToVideoArgs<'_,
|
||||
pub async fn enqueue_veo_3p1_text_to_video_webhook<R: IntoUrl>(
|
||||
args: EnqueueVeo3p1TextToVideoArgs<'_, R>
|
||||
) -> Result<WebhookResponse, FalErrorPlus> {
|
||||
let req = args.request;
|
||||
|
||||
let duration = args.duration
|
||||
let duration = req.duration
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueVeo3p1TextToVideoDurationSeconds::Four => "4s",
|
||||
EnqueueVeo3p1TextToVideoDurationSeconds::Six => "6s",
|
||||
@@ -83,7 +84,7 @@ pub async fn enqueue_veo_3p1_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let aspect_ratio = args.aspect_ratio
|
||||
let aspect_ratio = req.aspect_ratio
|
||||
.map(|aspect_ratio| match aspect_ratio {
|
||||
EnqueueVeo3p1TextToVideoAspectRatio::Auto => "auto",
|
||||
EnqueueVeo3p1TextToVideoAspectRatio::SixteenByNine => "16:9",
|
||||
@@ -91,7 +92,7 @@ pub async fn enqueue_veo_3p1_text_to_video_webhook<R: IntoUrl>(
|
||||
})
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let resolution = args.resolution
|
||||
let resolution = req.resolution
|
||||
.map(|resolution| match resolution {
|
||||
EnqueueVeo3p1TextToVideoResolution::SevenTwentyP => "720p",
|
||||
EnqueueVeo3p1TextToVideoResolution::TenEightyP => "1080p",
|
||||
@@ -99,16 +100,16 @@ pub async fn enqueue_veo_3p1_text_to_video_webhook<R: IntoUrl>(
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let request = Veo3p1TextToVideoInput {
|
||||
prompt: args.prompt,
|
||||
prompt: req.prompt,
|
||||
// Optionals
|
||||
duration,
|
||||
aspect_ratio,
|
||||
resolution,
|
||||
negative_prompt: args.negative_prompt,
|
||||
generate_audio: args.generate_audio,
|
||||
enhance_prompt: args.enhance_prompt,
|
||||
seed: args.seed,
|
||||
auto_fix: args.auto_fix,
|
||||
negative_prompt: req.negative_prompt,
|
||||
generate_audio: req.generate_audio,
|
||||
enhance_prompt: req.enhance_prompt,
|
||||
seed: req.seed,
|
||||
auto_fix: req.auto_fix,
|
||||
};
|
||||
|
||||
let result = veo_3p1_text_to_video(request)
|
||||
@@ -122,7 +123,7 @@ pub async fn enqueue_veo_3p1_text_to_video_webhook<R: IntoUrl>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::creds::fal_api_key::FalApiKey;
|
||||
use crate::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs, EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds, EnqueueVeo3p1TextToVideoResolution};
|
||||
use crate::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs, EnqueueVeo3p1TextToVideoRequest, EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds, EnqueueVeo3p1TextToVideoResolution};
|
||||
use errors::AnyhowResult;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
@@ -135,15 +136,17 @@ mod tests {
|
||||
let api_key = FalApiKey::from_str(&secret);
|
||||
|
||||
let args = EnqueueVeo3p1TextToVideoArgs {
|
||||
prompt: "An alien space ship hovers over new york city. it looks ominous, ready to attack. suddenly, it drops a bunch of ping pong balls on the city".to_string(),
|
||||
duration: Some(EnqueueVeo3p1TextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueVeo3p1TextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueVeo3p1TextToVideoResolution::TenEightyP),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
enhance_prompt: Some(true),
|
||||
auto_fix: Some(true),
|
||||
seed: None,
|
||||
request: EnqueueVeo3p1TextToVideoRequest {
|
||||
prompt: "An alien space ship hovers over new york city. it looks ominous, ready to attack. suddenly, it drops a bunch of ping pong balls on the city".to_string(),
|
||||
duration: Some(EnqueueVeo3p1TextToVideoDurationSeconds::Eight),
|
||||
aspect_ratio: Some(EnqueueVeo3p1TextToVideoAspectRatio::SixteenByNine),
|
||||
resolution: Some(EnqueueVeo3p1TextToVideoResolution::TenEightyP),
|
||||
generate_audio: Some(true),
|
||||
negative_prompt: None,
|
||||
enhance_prompt: Some(true),
|
||||
auto_fix: Some(true),
|
||||
seed: None,
|
||||
},
|
||||
api_key: &api_key,
|
||||
webhook_url: "https://example.com/webhook",
|
||||
};
|
||||
|
||||
+8
-4
@@ -26,7 +26,7 @@ use fal_client::requests::traits::fal_request_cost_calculator_trait::FalRequestC
|
||||
use fal_client::requests::webhook::image::edit::enqueue_gpt_image_1p5_edit_image_webhook::{enqueue_gpt_image_1p5_image_edit_webhook, EnqueueGptImage1p5EditImageArgs, EnqueueGptImage1p5EditImageBackground, EnqueueGptImage1p5EditImageInputFidelity, EnqueueGptImage1p5EditImageNumImages, EnqueueGptImage1p5EditImageQuality, EnqueueGptImage1p5EditImageRequest, EnqueueGptImage1p5EditImageSize};
|
||||
use fal_client::requests::webhook::image::text::enqueue_gpt_image_1p5_text_to_image_webhook::{enqueue_gpt_image_1p5_text_to_image_webhook, EnqueueGptImage1p5TextToImageArgs, EnqueueGptImage1p5TextToImageBackground, EnqueueGptImage1p5TextToImageNumImages, EnqueueGptImage1p5TextToImageQuality, EnqueueGptImage1p5TextToImageSize};
|
||||
use fal_client::requests::webhook::video::image::enqueue_kling_v2p5_turbo_pro_image_to_video_webhook::{enqueue_kling_v2p5_turbo_pro_image_to_video_webhook, EnqueueKlingV2p5TurboProImageToVideoArgs, EnqueueKlingV2p5TurboProImageToVideoRequest, EnqueueKlingV2p5TurboProImageToVideoDurationSeconds};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs, EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p5_turbo_pro_text_to_video_webhook::{enqueue_kling_v2p5_turbo_pro_text_to_video_webhook, EnqueueKlingV2p5TurboProTextToVideoArgs, EnqueueKlingV2p5TurboProTextToVideoRequest, EnqueueKlingV2p5TurboProTextToVideoAspectRatio, EnqueueKlingV2p5TurboProTextToVideoDurationSeconds};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::insert_generic_inference_job_for_fal_queue;
|
||||
@@ -214,17 +214,21 @@ pub async fn kling_2p5_turbo_pro_multi_function_video_gen_handler(
|
||||
None => EnqueueKlingV2p5TurboProTextToVideoAspectRatio::Square,
|
||||
};
|
||||
|
||||
let args = EnqueueKlingV2p5TurboProTextToVideoArgs {
|
||||
let t2v_request = EnqueueKlingV2p5TurboProTextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
};
|
||||
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
let args = EnqueueKlingV2p5TurboProTextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet: {}", cost);
|
||||
|
||||
attempt_wallet_deduction_else_common_web_error(
|
||||
|
||||
+8
-4
@@ -24,7 +24,7 @@ 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_v2p6_pro_image_to_video_webhook::{enqueue_kling_v2p6_pro_image_to_video_webhook, EnqueueKlingV2p6ProImageToVideoArgs, EnqueueKlingV2p6ProImageToVideoRequest, EnqueueKlingV2p6ProImageToVideoDurationSeconds};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs, EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds};
|
||||
use fal_client::requests::webhook::video::text::enqueue_kling_v2p6_pro_text_to_video_webhook::{enqueue_kling_v2p6_pro_text_to_video_webhook, EnqueueKlingV2p6ProTextToVideoArgs, EnqueueKlingV2p6ProTextToVideoRequest, EnqueueKlingV2p6ProTextToVideoAspectRatio, EnqueueKlingV2p6ProTextToVideoDurationSeconds};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
|
||||
@@ -210,17 +210,21 @@ pub async fn kling_2p6_pro_multi_function_video_gen_handler(
|
||||
None => EnqueueKlingV2p6ProTextToVideoAspectRatio::Square,
|
||||
};
|
||||
|
||||
let args = EnqueueKlingV2p6ProTextToVideoArgs {
|
||||
let t2v_request = EnqueueKlingV2p6ProTextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
generate_audio: request.generate_audio,
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
};
|
||||
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
let args = EnqueueKlingV2p6ProTextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet...");
|
||||
|
||||
|
||||
+8
-4
@@ -24,7 +24,7 @@ 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, EnqueueKling3p0ProImageToVideoRequest, EnqueueKling3p0ProImageToVideoAspectRatio, 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 fal_client::requests::webhook::video::text::enqueue_kling_3p0_pro_text_to_video_webhook::{enqueue_kling_3p0_pro_text_to_video_webhook, EnqueueKling3p0ProTextToVideoArgs, EnqueueKling3p0ProTextToVideoRequest, EnqueueKling3p0ProTextToVideoAspectRatio, EnqueueKling3p0ProTextToVideoDuration};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
|
||||
@@ -203,19 +203,23 @@ pub async fn kling_3p0_pro_multi_function_video_gen_handler(
|
||||
|
||||
let aspect_ratio = map_aspect_ratio_t2v(request.aspect_ratio);
|
||||
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
let t2v_request = EnqueueKling3p0ProTextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
generate_audio: Some(generate_audio),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
shot_type: None,
|
||||
};
|
||||
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
let args = EnqueueKling3p0ProTextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet...");
|
||||
|
||||
attempt_wallet_deduction_else_common_web_error(
|
||||
|
||||
+8
-4
@@ -24,7 +24,7 @@ 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, EnqueueKling3p0StandardImageToVideoRequest, EnqueueKling3p0StandardImageToVideoAspectRatio, 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 fal_client::requests::webhook::video::text::enqueue_kling_3p0_standard_text_to_video_webhook::{enqueue_kling_3p0_standard_text_to_video_webhook, EnqueueKling3p0StandardTextToVideoArgs, EnqueueKling3p0StandardTextToVideoRequest, EnqueueKling3p0StandardTextToVideoAspectRatio, EnqueueKling3p0StandardTextToVideoDuration};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
|
||||
@@ -203,19 +203,23 @@ pub async fn kling_3p0_standard_multi_function_video_gen_handler(
|
||||
|
||||
let aspect_ratio = map_aspect_ratio_t2v(request.aspect_ratio);
|
||||
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
let t2v_request = EnqueueKling3p0StandardTextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
generate_audio: Some(generate_audio),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
shot_type: None,
|
||||
};
|
||||
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
let args = EnqueueKling3p0StandardTextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet...");
|
||||
|
||||
attempt_wallet_deduction_else_common_web_error(
|
||||
|
||||
+9
-5
@@ -24,7 +24,7 @@ use enums::common::generation::common_generation_mode::CommonGenerationMode;
|
||||
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_sora_2_image_to_video_webhook::{enqueue_sora_2_image_to_video_webhook, EnqueueSora2ImageToVideoArgs, EnqueueSora2ImageToVideoAspectRatio, EnqueueSora2ImageToVideoDurationSeconds, EnqueueSora2ImageToVideoRequest, EnqueueSora2ImageToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_text_to_video_webhook::{enqueue_sora_2_text_to_video_webhook, EnqueueSora2TextToVideoArgs, EnqueueSora2TextToVideoAspectRatio, EnqueueSora2TextToVideoDurationSeconds, EnqueueSora2TextToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_text_to_video_webhook::{enqueue_sora_2_text_to_video_webhook, EnqueueSora2TextToVideoArgs, EnqueueSora2TextToVideoRequest, EnqueueSora2TextToVideoAspectRatio, EnqueueSora2TextToVideoDurationSeconds, EnqueueSora2TextToVideoResolution};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::insert_generic_inference_job_for_fal_queue;
|
||||
@@ -231,16 +231,14 @@ pub async fn sora_2_multi_function_video_gen_handler(
|
||||
None => EnqueueSora2TextToVideoResolution::SevenTwentyP,
|
||||
};
|
||||
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
let t2v_request = EnqueueSora2TextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
resolution: Some(resolution),
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet: {}", cost);
|
||||
|
||||
@@ -251,6 +249,12 @@ pub async fn sora_2_multi_function_video_gen_handler(
|
||||
&mut mysql_connection,
|
||||
).await?;
|
||||
|
||||
let args = EnqueueSora2TextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
fal_result = enqueue_sora_2_text_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
||||
+9
-5
@@ -24,7 +24,7 @@ use enums::common::generation::common_generation_mode::CommonGenerationMode;
|
||||
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_sora_2_pro_image_to_video_webhook::{enqueue_sora_2_pro_image_to_video_webhook, EnqueueSora2ProImageToVideoArgs, EnqueueSora2ProImageToVideoAspectRatio, EnqueueSora2ProImageToVideoDurationSeconds, EnqueueSora2ProImageToVideoRequest, EnqueueSora2ProImageToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_pro_text_to_video_webhook::{enqueue_sora_2_pro_text_to_video_webhook, EnqueueSora2ProTextToVideoArgs, EnqueueSora2ProTextToVideoAspectRatio, EnqueueSora2ProTextToVideoDurationSeconds, EnqueueSora2ProTextToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_sora_2_pro_text_to_video_webhook::{enqueue_sora_2_pro_text_to_video_webhook, EnqueueSora2ProTextToVideoArgs, EnqueueSora2ProTextToVideoRequest, EnqueueSora2ProTextToVideoAspectRatio, EnqueueSora2ProTextToVideoDurationSeconds, EnqueueSora2ProTextToVideoResolution};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::insert_generic_inference_job_for_fal_queue;
|
||||
@@ -233,16 +233,14 @@ pub async fn sora_2_pro_multi_function_video_gen_handler(
|
||||
None => EnqueueSora2ProTextToVideoResolution::TenEightyP,
|
||||
};
|
||||
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
let t2v_request = EnqueueSora2ProTextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
duration: Some(duration),
|
||||
aspect_ratio: Some(aspect_ratio),
|
||||
resolution: Some(resolution),
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet: {}", cost);
|
||||
|
||||
@@ -253,6 +251,12 @@ pub async fn sora_2_pro_multi_function_video_gen_handler(
|
||||
&mut mysql_connection,
|
||||
).await?;
|
||||
|
||||
let args = EnqueueSora2ProTextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
fal_result = enqueue_sora_2_pro_text_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
||||
+10
-6
@@ -25,7 +25,7 @@ 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_veo_3p1_first_last_frame_image_to_video_webhook::{enqueue_veo_3p1_first_last_frame_image_to_video_webhook, EnqueueVeo3p1FirstLastFrameImageToVideoArgs, EnqueueVeo3p1FirstLastFrameImageToVideoAspectRatio, EnqueueVeo3p1FirstLastFrameImageToVideoDurationSeconds, EnqueueVeo3p1FirstLastFrameImageToVideoRequest, EnqueueVeo3p1FirstLastFrameImageToVideoResolution};
|
||||
use fal_client::requests::webhook::video::image::enqueue_veo_3p1_image_to_video_webhook::{enqueue_veo_3p1_image_to_video_webhook, EnqueueVeo3p1ImageToVideoArgs, EnqueueVeo3p1ImageToVideoAspectRatio, EnqueueVeo3p1ImageToVideoDurationSeconds, EnqueueVeo3p1ImageToVideoRequest, EnqueueVeo3p1ImageToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs, EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds, EnqueueVeo3p1TextToVideoResolution};
|
||||
use fal_client::requests::webhook::video::text::enqueue_veo_3p1_text_to_video_webhook::{enqueue_veo_3p1_text_to_video_webhook, EnqueueVeo3p1TextToVideoArgs, EnqueueVeo3p1TextToVideoRequest, EnqueueVeo3p1TextToVideoAspectRatio, EnqueueVeo3p1TextToVideoDurationSeconds, EnqueueVeo3p1TextToVideoResolution};
|
||||
use http_server_common::request::get_request_ip::get_request_ip;
|
||||
use log::{error, info, warn};
|
||||
use mysql_queries::queries::generic_inference::fal::insert_generic_inference_job_for_fal_queue::insert_generic_inference_job_for_fal_queue;
|
||||
@@ -296,7 +296,7 @@ pub async fn veo_3p1_multi_function_video_gen_handler(
|
||||
None => EnqueueVeo3p1TextToVideoResolution::TenEightyP,
|
||||
};
|
||||
|
||||
let args = EnqueueVeo3p1TextToVideoArgs {
|
||||
let t2v_request = EnqueueVeo3p1TextToVideoRequest {
|
||||
prompt: request.prompt.as_deref().unwrap_or("").to_string(),
|
||||
negative_prompt: request.negative_prompt.clone(),
|
||||
duration: Some(duration),
|
||||
@@ -306,11 +306,9 @@ pub async fn veo_3p1_multi_function_video_gen_handler(
|
||||
enhance_prompt: Some(true),
|
||||
auto_fix: Some(true),
|
||||
seed: None,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
let cost = args.calculate_cost_in_cents();
|
||||
|
||||
let cost = t2v_request.calculate_cost_in_cents();
|
||||
|
||||
info!("Charging wallet: {}", cost);
|
||||
|
||||
@@ -321,6 +319,12 @@ pub async fn veo_3p1_multi_function_video_gen_handler(
|
||||
&mut mysql_connection,
|
||||
).await?;
|
||||
|
||||
let args = EnqueueVeo3p1TextToVideoArgs {
|
||||
request: t2v_request,
|
||||
webhook_url: &server_state.fal.webhook_url,
|
||||
api_key: &server_state.fal.api_key,
|
||||
};
|
||||
|
||||
fal_result = enqueue_veo_3p1_text_to_video_webhook(args)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
||||
Reference in new issue
Block a user