API Node
- Image
- Video
Kling Image to Video - ComfyUI 原生节点文档
Kling Image to Video - ComfyUI 原生节点文档
使用Kling的AI技术将静态图像转换为动态视频的节点
Kling Image to Video 节点可以通过Kling的图像到视频API,将静态图像转换为动态视频内容。
参数说明
基本参数
以下所有参数均为必需参数:
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
start_frame | 图像 | - | 输入的源图像 |
prompt | 字符串 | "" | 描述视频动作和内容的文本提示词 |
negative_prompt | 字符串 | "" | 指定不希望在视频中出现的元素 |
cfg_scale | 浮点数 | 7.0 | 配置缩放值,控制对提示词的遵循程度 |
model_name | 选择项 | ”kling-v1-5” | 使用的模型类型 |
aspect_ratio | 选择项 | ”16:9” | 输出视频的宽高比 |
duration | 选择项 | ”5s” | 生成视频的持续时间 |
mode | 选择项 | ”pro” | 视频生成模式 |
输出
输出 | 类型 | 说明 |
---|---|---|
VIDEO | 视频 | 生成的视频结果 |
video_id | 字符串 | 视频的唯一标识符 |
duration | 字符串 | 视频的实际持续时间 |
源码参考
[节点源码 (更新于2025-05-03)]
class KlingImage2VideoNode(KlingNodeBase):
"""Kling Image to Video Node"""
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"start_frame": model_field_to_node_input(
IO.IMAGE, KlingImage2VideoRequest, "image"
),
"prompt": model_field_to_node_input(
IO.STRING, KlingImage2VideoRequest, "prompt", multiline=True
),
"negative_prompt": model_field_to_node_input(
IO.STRING,
KlingImage2VideoRequest,
"negative_prompt",
multiline=True,
),
"model_name": model_field_to_node_input(
IO.COMBO,
KlingImage2VideoRequest,
"model_name",
enum_type=KlingVideoGenModelName,
),
"cfg_scale": model_field_to_node_input(
IO.FLOAT, KlingImage2VideoRequest, "cfg_scale"
),
"mode": model_field_to_node_input(
IO.COMBO,
KlingImage2VideoRequest,
"mode",
enum_type=KlingVideoGenMode,
),
"aspect_ratio": model_field_to_node_input(
IO.COMBO,
KlingImage2VideoRequest,
"aspect_ratio",
enum_type=KlingVideoGenAspectRatio,
),
"duration": model_field_to_node_input(
IO.COMBO,
KlingImage2VideoRequest,
"duration",
enum_type=KlingVideoGenDuration,
),
},
"hidden": {"auth_token": "AUTH_TOKEN_COMFY_ORG"},
}
RETURN_TYPES = ("VIDEO", "STRING", "STRING")
RETURN_NAMES = ("VIDEO", "video_id", "duration")
DESCRIPTION = "Kling Image to Video Node"
def get_response(self, task_id: str, auth_token: str) -> KlingImage2VideoResponse:
return poll_until_finished(
auth_token,
ApiEndpoint(
path=f"{PATH_IMAGE_TO_VIDEO}/{task_id}",
method=HttpMethod.GET,
request_model=KlingImage2VideoRequest,
response_model=KlingImage2VideoResponse,
),
)
def api_call(
self,
start_frame: torch.Tensor,
prompt: str,
negative_prompt: str,
model_name: str,
cfg_scale: float,
mode: str,
aspect_ratio: str,
duration: str,
camera_control: Optional[KlingCameraControl] = None,
end_frame: Optional[torch.Tensor] = None,
auth_token: Optional[str] = None,
) -> tuple[VideoFromFile]:
validate_prompts(prompt, negative_prompt, MAX_PROMPT_LENGTH_I2V)
initial_operation = SynchronousOperation(
endpoint=ApiEndpoint(
path=PATH_IMAGE_TO_VIDEO,
method=HttpMethod.POST,
request_model=KlingImage2VideoRequest,
response_model=KlingImage2VideoResponse,
),
request=KlingImage2VideoRequest(
model_name=KlingVideoGenModelName(model_name),
image=tensor_to_base64_string(start_frame),
image_tail=(
tensor_to_base64_string(end_frame)
if end_frame is not None
else None
),
prompt=prompt,
negative_prompt=negative_prompt if negative_prompt else None,
cfg_scale=cfg_scale,
mode=KlingVideoGenMode(mode),
aspect_ratio=KlingVideoGenAspectRatio(aspect_ratio),
duration=KlingVideoGenDuration(duration),
camera_control=camera_control,
),
auth_token=auth_token,
)
task_creation_response = initial_operation.execute()
validate_task_creation_response(task_creation_response)
task_id = task_creation_response.data.task_id
final_response = self.get_response(task_id, auth_token)
validate_video_result_response(final_response)
video = get_video_from_response(final_response)
return video_result_to_node_output(video)