mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-26 06:10:15 +08:00
feat(api-nodes): add support for seedance-1-0-pro-fast model
This commit is contained in:
parent
35fa091340
commit
65cd8887cc
144
comfy_api_nodes/apis/bytedance_api.py
Normal file
144
comfy_api_nodes/apis/bytedance_api.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class Text2ImageTaskCreationRequest(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
prompt: str = Field(...)
|
||||||
|
response_format: str | None = Field("url")
|
||||||
|
size: str | None = Field(None)
|
||||||
|
seed: int | None = Field(0, ge=0, le=2147483647)
|
||||||
|
guidance_scale: float | None = Field(..., ge=1.0, le=10.0)
|
||||||
|
watermark: bool | None = Field(True)
|
||||||
|
|
||||||
|
|
||||||
|
class Image2ImageTaskCreationRequest(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
prompt: str = Field(...)
|
||||||
|
response_format: str | None = Field("url")
|
||||||
|
image: str = Field(..., description="Base64 encoded string or image URL")
|
||||||
|
size: str | None = Field("adaptive")
|
||||||
|
seed: int | None = Field(..., ge=0, le=2147483647)
|
||||||
|
guidance_scale: float | None = Field(..., ge=1.0, le=10.0)
|
||||||
|
watermark: bool | None = Field(True)
|
||||||
|
|
||||||
|
|
||||||
|
class Seedream4Options(BaseModel):
|
||||||
|
max_images: int = Field(15)
|
||||||
|
|
||||||
|
|
||||||
|
class Seedream4TaskCreationRequest(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
prompt: str = Field(...)
|
||||||
|
response_format: str = Field("url")
|
||||||
|
image: list[str] | None = Field(None, description="Image URLs")
|
||||||
|
size: str = Field(...)
|
||||||
|
seed: int = Field(..., ge=0, le=2147483647)
|
||||||
|
sequential_image_generation: str = Field("disabled")
|
||||||
|
sequential_image_generation_options: Seedream4Options = Field(Seedream4Options(max_images=15))
|
||||||
|
watermark: bool = Field(True)
|
||||||
|
|
||||||
|
|
||||||
|
class ImageTaskCreationResponse(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
created: int = Field(..., description="Unix timestamp (in seconds) indicating time when the request was created.")
|
||||||
|
data: list = Field([], description="Contains information about the generated image(s).")
|
||||||
|
error: dict = Field({}, description="Contains `code` and `message` fields in case of error.")
|
||||||
|
|
||||||
|
|
||||||
|
class TaskTextContent(BaseModel):
|
||||||
|
type: str = Field("text")
|
||||||
|
text: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskImageContentUrl(BaseModel):
|
||||||
|
url: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskImageContent(BaseModel):
|
||||||
|
type: str = Field("image_url")
|
||||||
|
image_url: TaskImageContentUrl = Field(...)
|
||||||
|
role: Literal["first_frame", "last_frame", "reference_image"] | None = Field(None)
|
||||||
|
|
||||||
|
|
||||||
|
class Text2VideoTaskCreationRequest(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
content: list[TaskTextContent] = Field(..., min_length=1)
|
||||||
|
|
||||||
|
|
||||||
|
class Image2VideoTaskCreationRequest(BaseModel):
|
||||||
|
model: str = Field(...)
|
||||||
|
content: list[TaskTextContent | TaskImageContent] = Field(..., min_length=2)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskCreationResponse(BaseModel):
|
||||||
|
id: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskStatusError(BaseModel):
|
||||||
|
code: str = Field(...)
|
||||||
|
message: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskStatusResult(BaseModel):
|
||||||
|
video_url: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskStatusResponse(BaseModel):
|
||||||
|
id: str = Field(...)
|
||||||
|
model: str = Field(...)
|
||||||
|
status: Literal["queued", "running", "cancelled", "succeeded", "failed"] = Field(...)
|
||||||
|
error: TaskStatusError | None = Field(None)
|
||||||
|
content: TaskStatusResult | None = Field(None)
|
||||||
|
|
||||||
|
|
||||||
|
RECOMMENDED_PRESETS = [
|
||||||
|
("1024x1024 (1:1)", 1024, 1024),
|
||||||
|
("864x1152 (3:4)", 864, 1152),
|
||||||
|
("1152x864 (4:3)", 1152, 864),
|
||||||
|
("1280x720 (16:9)", 1280, 720),
|
||||||
|
("720x1280 (9:16)", 720, 1280),
|
||||||
|
("832x1248 (2:3)", 832, 1248),
|
||||||
|
("1248x832 (3:2)", 1248, 832),
|
||||||
|
("1512x648 (21:9)", 1512, 648),
|
||||||
|
("2048x2048 (1:1)", 2048, 2048),
|
||||||
|
("Custom", None, None),
|
||||||
|
]
|
||||||
|
|
||||||
|
RECOMMENDED_PRESETS_SEEDREAM_4 = [
|
||||||
|
("2048x2048 (1:1)", 2048, 2048),
|
||||||
|
("2304x1728 (4:3)", 2304, 1728),
|
||||||
|
("1728x2304 (3:4)", 1728, 2304),
|
||||||
|
("2560x1440 (16:9)", 2560, 1440),
|
||||||
|
("1440x2560 (9:16)", 1440, 2560),
|
||||||
|
("2496x1664 (3:2)", 2496, 1664),
|
||||||
|
("1664x2496 (2:3)", 1664, 2496),
|
||||||
|
("3024x1296 (21:9)", 3024, 1296),
|
||||||
|
("4096x4096 (1:1)", 4096, 4096),
|
||||||
|
("Custom", None, None),
|
||||||
|
]
|
||||||
|
|
||||||
|
# The time in this dictionary are given for 10 seconds duration.
|
||||||
|
VIDEO_TASKS_EXECUTION_TIME = {
|
||||||
|
"seedance-1-0-lite-t2v-250428": {
|
||||||
|
"480p": 40,
|
||||||
|
"720p": 60,
|
||||||
|
"1080p": 90,
|
||||||
|
},
|
||||||
|
"seedance-1-0-lite-i2v-250428": {
|
||||||
|
"480p": 40,
|
||||||
|
"720p": 60,
|
||||||
|
"1080p": 90,
|
||||||
|
},
|
||||||
|
"seedance-1-0-pro-250528": {
|
||||||
|
"480p": 70,
|
||||||
|
"720p": 85,
|
||||||
|
"1080p": 115,
|
||||||
|
},
|
||||||
|
"seedance-1-0-pro-fast-251015": {
|
||||||
|
"480p": 50,
|
||||||
|
"720p": 65,
|
||||||
|
"1080p": 100,
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -1,13 +1,27 @@
|
|||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
from enum import Enum
|
|
||||||
from typing import Literal, Optional, Union
|
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
from pydantic import BaseModel, Field
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from comfy_api.latest import IO, ComfyExtension
|
from comfy_api.latest import IO, ComfyExtension
|
||||||
|
from comfy_api_nodes.apis.bytedance_api import (
|
||||||
|
RECOMMENDED_PRESETS,
|
||||||
|
RECOMMENDED_PRESETS_SEEDREAM_4,
|
||||||
|
VIDEO_TASKS_EXECUTION_TIME,
|
||||||
|
Image2ImageTaskCreationRequest,
|
||||||
|
Image2VideoTaskCreationRequest,
|
||||||
|
ImageTaskCreationResponse,
|
||||||
|
Seedream4Options,
|
||||||
|
Seedream4TaskCreationRequest,
|
||||||
|
TaskCreationResponse,
|
||||||
|
TaskImageContent,
|
||||||
|
TaskImageContentUrl,
|
||||||
|
TaskStatusResponse,
|
||||||
|
TaskTextContent,
|
||||||
|
Text2ImageTaskCreationRequest,
|
||||||
|
Text2VideoTaskCreationRequest,
|
||||||
|
)
|
||||||
from comfy_api_nodes.util import (
|
from comfy_api_nodes.util import (
|
||||||
ApiEndpoint,
|
ApiEndpoint,
|
||||||
download_url_to_image_tensor,
|
download_url_to_image_tensor,
|
||||||
@ -29,162 +43,6 @@ BYTEPLUS_TASK_ENDPOINT = "/proxy/byteplus/api/v3/contents/generations/tasks"
|
|||||||
BYTEPLUS_TASK_STATUS_ENDPOINT = "/proxy/byteplus/api/v3/contents/generations/tasks" # + /{task_id}
|
BYTEPLUS_TASK_STATUS_ENDPOINT = "/proxy/byteplus/api/v3/contents/generations/tasks" # + /{task_id}
|
||||||
|
|
||||||
|
|
||||||
class Text2ImageModelName(str, Enum):
|
|
||||||
seedream_3 = "seedream-3-0-t2i-250415"
|
|
||||||
|
|
||||||
|
|
||||||
class Image2ImageModelName(str, Enum):
|
|
||||||
seededit_3 = "seededit-3-0-i2i-250628"
|
|
||||||
|
|
||||||
|
|
||||||
class Text2VideoModelName(str, Enum):
|
|
||||||
seedance_1_pro = "seedance-1-0-pro-250528"
|
|
||||||
seedance_1_lite = "seedance-1-0-lite-t2v-250428"
|
|
||||||
|
|
||||||
|
|
||||||
class Image2VideoModelName(str, Enum):
|
|
||||||
"""note(August 31): Pro model only supports FirstFrame: https://docs.byteplus.com/en/docs/ModelArk/1520757"""
|
|
||||||
|
|
||||||
seedance_1_pro = "seedance-1-0-pro-250528"
|
|
||||||
seedance_1_lite = "seedance-1-0-lite-i2v-250428"
|
|
||||||
|
|
||||||
|
|
||||||
class Text2ImageTaskCreationRequest(BaseModel):
|
|
||||||
model: Text2ImageModelName = Text2ImageModelName.seedream_3
|
|
||||||
prompt: str = Field(...)
|
|
||||||
response_format: Optional[str] = Field("url")
|
|
||||||
size: Optional[str] = Field(None)
|
|
||||||
seed: Optional[int] = Field(0, ge=0, le=2147483647)
|
|
||||||
guidance_scale: Optional[float] = Field(..., ge=1.0, le=10.0)
|
|
||||||
watermark: Optional[bool] = Field(True)
|
|
||||||
|
|
||||||
|
|
||||||
class Image2ImageTaskCreationRequest(BaseModel):
|
|
||||||
model: Image2ImageModelName = Image2ImageModelName.seededit_3
|
|
||||||
prompt: str = Field(...)
|
|
||||||
response_format: Optional[str] = Field("url")
|
|
||||||
image: str = Field(..., description="Base64 encoded string or image URL")
|
|
||||||
size: Optional[str] = Field("adaptive")
|
|
||||||
seed: Optional[int] = Field(..., ge=0, le=2147483647)
|
|
||||||
guidance_scale: Optional[float] = Field(..., ge=1.0, le=10.0)
|
|
||||||
watermark: Optional[bool] = Field(True)
|
|
||||||
|
|
||||||
|
|
||||||
class Seedream4Options(BaseModel):
|
|
||||||
max_images: int = Field(15)
|
|
||||||
|
|
||||||
|
|
||||||
class Seedream4TaskCreationRequest(BaseModel):
|
|
||||||
model: str = Field("seedream-4-0-250828")
|
|
||||||
prompt: str = Field(...)
|
|
||||||
response_format: str = Field("url")
|
|
||||||
image: Optional[list[str]] = Field(None, description="Image URLs")
|
|
||||||
size: str = Field(...)
|
|
||||||
seed: int = Field(..., ge=0, le=2147483647)
|
|
||||||
sequential_image_generation: str = Field("disabled")
|
|
||||||
sequential_image_generation_options: Seedream4Options = Field(Seedream4Options(max_images=15))
|
|
||||||
watermark: bool = Field(True)
|
|
||||||
|
|
||||||
|
|
||||||
class ImageTaskCreationResponse(BaseModel):
|
|
||||||
model: str = Field(...)
|
|
||||||
created: int = Field(..., description="Unix timestamp (in seconds) indicating time when the request was created.")
|
|
||||||
data: list = Field([], description="Contains information about the generated image(s).")
|
|
||||||
error: dict = Field({}, description="Contains `code` and `message` fields in case of error.")
|
|
||||||
|
|
||||||
|
|
||||||
class TaskTextContent(BaseModel):
|
|
||||||
type: str = Field("text")
|
|
||||||
text: str = Field(...)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskImageContentUrl(BaseModel):
|
|
||||||
url: str = Field(...)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskImageContent(BaseModel):
|
|
||||||
type: str = Field("image_url")
|
|
||||||
image_url: TaskImageContentUrl = Field(...)
|
|
||||||
role: Optional[Literal["first_frame", "last_frame", "reference_image"]] = Field(None)
|
|
||||||
|
|
||||||
|
|
||||||
class Text2VideoTaskCreationRequest(BaseModel):
|
|
||||||
model: Text2VideoModelName = Text2VideoModelName.seedance_1_pro
|
|
||||||
content: list[TaskTextContent] = Field(..., min_length=1)
|
|
||||||
|
|
||||||
|
|
||||||
class Image2VideoTaskCreationRequest(BaseModel):
|
|
||||||
model: Image2VideoModelName = Image2VideoModelName.seedance_1_pro
|
|
||||||
content: list[Union[TaskTextContent, TaskImageContent]] = Field(..., min_length=2)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskCreationResponse(BaseModel):
|
|
||||||
id: str = Field(...)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskStatusError(BaseModel):
|
|
||||||
code: str = Field(...)
|
|
||||||
message: str = Field(...)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskStatusResult(BaseModel):
|
|
||||||
video_url: str = Field(...)
|
|
||||||
|
|
||||||
|
|
||||||
class TaskStatusResponse(BaseModel):
|
|
||||||
id: str = Field(...)
|
|
||||||
model: str = Field(...)
|
|
||||||
status: Literal["queued", "running", "cancelled", "succeeded", "failed"] = Field(...)
|
|
||||||
error: Optional[TaskStatusError] = Field(None)
|
|
||||||
content: Optional[TaskStatusResult] = Field(None)
|
|
||||||
|
|
||||||
|
|
||||||
RECOMMENDED_PRESETS = [
|
|
||||||
("1024x1024 (1:1)", 1024, 1024),
|
|
||||||
("864x1152 (3:4)", 864, 1152),
|
|
||||||
("1152x864 (4:3)", 1152, 864),
|
|
||||||
("1280x720 (16:9)", 1280, 720),
|
|
||||||
("720x1280 (9:16)", 720, 1280),
|
|
||||||
("832x1248 (2:3)", 832, 1248),
|
|
||||||
("1248x832 (3:2)", 1248, 832),
|
|
||||||
("1512x648 (21:9)", 1512, 648),
|
|
||||||
("2048x2048 (1:1)", 2048, 2048),
|
|
||||||
("Custom", None, None),
|
|
||||||
]
|
|
||||||
|
|
||||||
RECOMMENDED_PRESETS_SEEDREAM_4 = [
|
|
||||||
("2048x2048 (1:1)", 2048, 2048),
|
|
||||||
("2304x1728 (4:3)", 2304, 1728),
|
|
||||||
("1728x2304 (3:4)", 1728, 2304),
|
|
||||||
("2560x1440 (16:9)", 2560, 1440),
|
|
||||||
("1440x2560 (9:16)", 1440, 2560),
|
|
||||||
("2496x1664 (3:2)", 2496, 1664),
|
|
||||||
("1664x2496 (2:3)", 1664, 2496),
|
|
||||||
("3024x1296 (21:9)", 3024, 1296),
|
|
||||||
("4096x4096 (1:1)", 4096, 4096),
|
|
||||||
("Custom", None, None),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The time in this dictionary are given for 10 seconds duration.
|
|
||||||
VIDEO_TASKS_EXECUTION_TIME = {
|
|
||||||
"seedance-1-0-lite-t2v-250428": {
|
|
||||||
"480p": 40,
|
|
||||||
"720p": 60,
|
|
||||||
"1080p": 90,
|
|
||||||
},
|
|
||||||
"seedance-1-0-lite-i2v-250428": {
|
|
||||||
"480p": 40,
|
|
||||||
"720p": 60,
|
|
||||||
"1080p": 90,
|
|
||||||
},
|
|
||||||
"seedance-1-0-pro-250528": {
|
|
||||||
"480p": 70,
|
|
||||||
"720p": 85,
|
|
||||||
"1080p": 115,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_image_url_from_response(response: ImageTaskCreationResponse) -> str:
|
def get_image_url_from_response(response: ImageTaskCreationResponse) -> str:
|
||||||
if response.error:
|
if response.error:
|
||||||
error_msg = f"ByteDance request failed. Code: {response.error['code']}, message: {response.error['message']}"
|
error_msg = f"ByteDance request failed. Code: {response.error['code']}, message: {response.error['message']}"
|
||||||
@ -194,13 +52,6 @@ def get_image_url_from_response(response: ImageTaskCreationResponse) -> str:
|
|||||||
return response.data[0]["url"]
|
return response.data[0]["url"]
|
||||||
|
|
||||||
|
|
||||||
def get_video_url_from_task_status(response: TaskStatusResponse) -> Union[str, None]:
|
|
||||||
"""Returns the video URL from the task status response if it exists."""
|
|
||||||
if hasattr(response, "content") and response.content:
|
|
||||||
return response.content.video_url
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class ByteDanceImageNode(IO.ComfyNode):
|
class ByteDanceImageNode(IO.ComfyNode):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -211,12 +62,7 @@ class ByteDanceImageNode(IO.ComfyNode):
|
|||||||
category="api node/image/ByteDance",
|
category="api node/image/ByteDance",
|
||||||
description="Generate images using ByteDance models via api based on prompt",
|
description="Generate images using ByteDance models via api based on prompt",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input("model", options=["seedream-3-0-t2i-250415"]),
|
||||||
"model",
|
|
||||||
options=Text2ImageModelName,
|
|
||||||
default=Text2ImageModelName.seedream_3,
|
|
||||||
tooltip="Model name",
|
|
||||||
),
|
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
multiline=True,
|
multiline=True,
|
||||||
@ -335,12 +181,7 @@ class ByteDanceImageEditNode(IO.ComfyNode):
|
|||||||
category="api node/image/ByteDance",
|
category="api node/image/ByteDance",
|
||||||
description="Edit images using ByteDance models via api based on prompt",
|
description="Edit images using ByteDance models via api based on prompt",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input("model", options=["seededit-3-0-i2i-250628"]),
|
||||||
"model",
|
|
||||||
options=Image2ImageModelName,
|
|
||||||
default=Image2ImageModelName.seededit_3,
|
|
||||||
tooltip="Model name",
|
|
||||||
),
|
|
||||||
IO.Image.Input(
|
IO.Image.Input(
|
||||||
"image",
|
"image",
|
||||||
tooltip="The base image to edit",
|
tooltip="The base image to edit",
|
||||||
@ -607,9 +448,8 @@ class ByteDanceTextToVideoNode(IO.ComfyNode):
|
|||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=Text2VideoModelName,
|
options=["seedance-1-0-pro-250528", "seedance-1-0-lite-t2v-250428", "seedance-1-0-pro-fast-251015"],
|
||||||
default=Text2VideoModelName.seedance_1_pro,
|
default="seedance-1-0-pro-fast-251015",
|
||||||
tooltip="Model name",
|
|
||||||
),
|
),
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@ -714,9 +554,8 @@ class ByteDanceImageToVideoNode(IO.ComfyNode):
|
|||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=Image2VideoModelName,
|
options=["seedance-1-0-pro-250528", "seedance-1-0-lite-t2v-250428", "seedance-1-0-pro-fast-251015"],
|
||||||
default=Image2VideoModelName.seedance_1_pro,
|
default="seedance-1-0-pro-fast-251015",
|
||||||
tooltip="Model name",
|
|
||||||
),
|
),
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@ -833,9 +672,8 @@ class ByteDanceFirstLastFrameNode(IO.ComfyNode):
|
|||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=[model.value for model in Image2VideoModelName],
|
options=["seedance-1-0-pro-250528", "seedance-1-0-lite-i2v-250428"],
|
||||||
default=Image2VideoModelName.seedance_1_lite.value,
|
default="seedance-1-0-lite-i2v-250428",
|
||||||
tooltip="Model name",
|
|
||||||
),
|
),
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@ -968,9 +806,8 @@ class ByteDanceImageReferenceNode(IO.ComfyNode):
|
|||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input(
|
||||||
"model",
|
"model",
|
||||||
options=[Image2VideoModelName.seedance_1_lite.value],
|
options=["seedance-1-0-pro-250528", "seedance-1-0-lite-i2v-250428"],
|
||||||
default=Image2VideoModelName.seedance_1_lite.value,
|
default="seedance-1-0-lite-i2v-250428",
|
||||||
tooltip="Model name",
|
|
||||||
),
|
),
|
||||||
IO.String.Input(
|
IO.String.Input(
|
||||||
"prompt",
|
"prompt",
|
||||||
@ -1069,8 +906,8 @@ class ByteDanceImageReferenceNode(IO.ComfyNode):
|
|||||||
|
|
||||||
async def process_video_task(
|
async def process_video_task(
|
||||||
cls: type[IO.ComfyNode],
|
cls: type[IO.ComfyNode],
|
||||||
payload: Union[Text2VideoTaskCreationRequest, Image2VideoTaskCreationRequest],
|
payload: Text2VideoTaskCreationRequest | Image2VideoTaskCreationRequest,
|
||||||
estimated_duration: Optional[int],
|
estimated_duration: int | None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
initial_response = await sync_op(
|
initial_response = await sync_op(
|
||||||
cls,
|
cls,
|
||||||
@ -1085,7 +922,7 @@ async def process_video_task(
|
|||||||
estimated_duration=estimated_duration,
|
estimated_duration=estimated_duration,
|
||||||
response_model=TaskStatusResponse,
|
response_model=TaskStatusResponse,
|
||||||
)
|
)
|
||||||
return IO.NodeOutput(await download_url_to_video_output(get_video_url_from_task_status(response)))
|
return IO.NodeOutput(await download_url_to_video_output(response.content.video_url))
|
||||||
|
|
||||||
|
|
||||||
def raise_if_text_params(prompt: str, text_params: list[str]) -> None:
|
def raise_if_text_params(prompt: str, text_params: list[str]) -> None:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user