added kling 2.6 image to video

This commit is contained in:
Steve Tietze
2025-12-22 12:32:03 +07:00
parent 773c811181
commit a1cc46a046
4 changed files with 415 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
spec to create a new node for kling , this is a video mode... which is image to text.
POST
/api/v1/jobs/createTask
Create Task
Create a new generation task
Request Parameters
The API accepts a JSON payload with the following structure:
Request Body Structure
{
"model": "string",
"callBackUrl": "string (optional)",
"input": {
// Input parameters based on form configuration
}
}
Root Level Parameters
model
Required
string
The model name to use for generation
Example:
"kling-2.6/image-to-video"
callBackUrl
Optional
string
Callback URL for task completion notifications. Optional parameter. If provided, the system will send POST requests to this URL when the task completes (success or failure). If not provided, no callback notifications will be sent.
Example:
"https://your-domain.com/api/callback"
Input Object Parameters
The input object contains the following parameters based on the form configuration:
input.prompt
Required
string
The text prompt used to generate the video
Max length: 1000 characters
Example:
"In a bright rehearsal room, sunlight streams through the window, and a standing microphone is placed in the center of the room. [Campus band female lead singer] stands in front of the microphone with her eyes closed, while the other members stand around her. [Campus band female lead singer, full voice] leads: \"I will try to fix you, with all my heart and soul...\" The background is an a cappella harmony, and the camera slowly circles around the band members."
input.image_urls
Required
array(URL)
The URL of the image used to generate video
File URL after upload, not file content; Accepted types: image/jpeg, image/png, image/webp; Max size: 10.0MB
Example:
["https://static.aiquickdraw.com/tools/example/1764851002741_i0lEiI8I.png"]
input.sound
Required
boolean
This parameter is used to specify whether the generated video contains sound
Boolean value (true/false)
Example:
false
input.duration
Required
string
Duration of the video in seconds
Available options:
5
-
5
10
-
10
Example:
"5"
Request Example
cURL
JavaScript
Python
import requests
import json
url = "https://api.kie.ai/api/v1/jobs/createTask"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
}
payload = {
"model": "kling-2.6/image-to-video",
"callBackUrl": "https://your-domain.com/api/callback",
"input": {
"prompt": "In a bright rehearsal room, sunlight streams through the window, and a standing microphone is placed in the center of the room. [Campus band female lead singer] stands in front of the microphone with her eyes closed, while the other members stand around her. [Campus band female lead singer, full voice] leads: \"I will try to fix you, with all my heart and soul...\" The background is an a cappella harmony, and the camera slowly circles around the band members.",
"image_urls": [
"https://static.aiquickdraw.com/tools/example/1764851002741_i0lEiI8I.png"
],
"sound": false,
"duration": "5"
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
result = response.json()
print(result)
Response Example
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_12345678"
}
}
Response Fields
code
Status code, 200 for success, others for failure
message
Response message, error description when failed
data.taskId
Task ID for querying task status
Callback Notifications
When you provide the callBackUrl parameter when creating a task, the system will send POST requests to the specified URL upon task completion (success or failure).
Success Callback Example
{
"code": 200,
"data": {
"completeTime": 1755599644000,
"consumeCredits": 100,
"costTime": 8,
"createTime": 1755599634000,
"model": "kling-2.6/image-to-video",
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"kling-2.6/image-to-video\",\"input\":{\"prompt\":\"In a bright rehearsal room, sunlight streams through the window, and a standing microphone is placed in the center of the room. [Campus band female lead singer] stands in front of the microphone with her eyes closed, while the other members stand around her. [Campus band female lead singer, full voice] leads: \\"I will try to fix you, with all my heart and soul...\\" The background is an a cappella harmony, and the camera slowly circles around the band members.\",\"image_urls\":[\"https://static.aiquickdraw.com/tools/example/1764851002741_i0lEiI8I.png\"],\"sound\":false,\"duration\":\"5\"}}",
"remainedCredits": 2510330,
"resultJson": "{\"resultUrls\":[\"https://example.com/generated-image.jpg\"]}",
"state": "success",
"taskId": "e989621f54392584b05867f87b160672",
"updateTime": 1755599644000
},
"msg": "Playground task completed successfully."
}
Failure Callback Example
{
"code": 501,
"data": {
"completeTime": 1755597081000,
"consumeCredits": 0,
"costTime": 0,
"createTime": 1755596341000,
"failCode": "500",
"failMsg": "Internal server error",
"model": "kling-2.6/image-to-video",
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"kling-2.6/image-to-video\",\"input\":{\"prompt\":\"In a bright rehearsal room, sunlight streams through the window, and a standing microphone is placed in the center of the room. [Campus band female lead singer] stands in front of the microphone with her eyes closed, while the other members stand around her. [Campus band female lead singer, full voice] leads: \\"I will try to fix you, with all my heart and soul...\\" The background is an a cappella harmony, and the camera slowly circles around the band members.\",\"image_urls\":[\"https://static.aiquickdraw.com/tools/example/1764851002741_i0lEiI8I.png\"],\"sound\":false,\"duration\":\"5\"}}",
"remainedCredits": 2510430,
"state": "fail",
"taskId": "bd3a37c523149e4adf45a3ddb5faf1a8",
"updateTime": 1755597097000
},
"msg": "Playground task failed."
}
+134
View File
@@ -0,0 +1,134 @@
"""Kling 2.6 image-to-video helper."""
import json
import time
from typing import Any
import torch
from .auth import _load_api_key
from .credits import _log_remaining_credits
from .http import TransientKieError, requests
from .jobs import _poll_task_until_complete
from .log import _log
from .results import _extract_result_urls
from .upload import _image_tensor_to_png_bytes, _truncate_url, _upload_image
from .validation import _validate_prompt
from .video import _download_video, _write_video_to_temp_file
CREATE_TASK_URL = "https://api.kie.ai/api/v1/jobs/createTask"
MODEL_NAME = "kling-2.6/image-to-video"
PROMPT_MAX_LENGTH = 1000
DURATION_OPTIONS = ["5", "10"]
def _validate_options(duration: str, sound: bool) -> None:
if duration not in DURATION_OPTIONS:
raise RuntimeError("Invalid duration. Use the pinned enum options.")
if not isinstance(sound, bool):
raise RuntimeError("sound must be a boolean value.")
def _validate_image_input(images: torch.Tensor | None) -> torch.Tensor:
if images is None:
raise RuntimeError("images input is required.")
if not isinstance(images, torch.Tensor):
raise RuntimeError("images input must be a tensor batch.")
if images.dim() != 4 or images.shape[-1] != 3:
raise RuntimeError("images input must have shape [B, H, W, 3].")
if images.shape[0] < 1:
raise RuntimeError("images input batch is empty.")
return images
def _create_kling_task(api_key: str, payload: dict[str, Any]) -> tuple[str, str]:
try:
response = requests.post(
CREATE_TASK_URL,
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json=payload,
timeout=30,
)
except requests.RequestException as exc:
raise RuntimeError(f"Failed to call createTask endpoint: {exc}") from exc
if response.status_code == 429 or response.status_code >= 500:
raise TransientKieError(
f"createTask returned HTTP {response.status_code}: {response.text}", status_code=response.status_code
)
try:
payload_json: Any = response.json()
except json.JSONDecodeError as exc:
raise RuntimeError("createTask endpoint did not return valid JSON.") from exc
if payload_json.get("code") != 200:
message = payload_json.get("message") or payload_json.get("msg")
raise RuntimeError(f"createTask endpoint returned error code {payload_json.get('code')}: {message}")
task_id = (payload_json.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError("createTask endpoint did not return a taskId.")
return task_id, response.text
def run_kling26_i2v(
prompt: str,
images: torch.Tensor,
duration: str = "5",
sound: bool = False,
poll_interval_s: float = 1.0,
timeout_s: int = 600,
log: bool = True,
) -> str:
_validate_prompt(prompt, max_length=PROMPT_MAX_LENGTH)
_validate_options(duration, sound)
images = _validate_image_input(images)
api_key = _load_api_key()
if images.shape[0] > 1:
_log(log, f"More than 1 image provided ({images.shape[0]}); only the first will be used.")
_log(log, "Uploading source image for Kling 2.6 I2V...")
png_bytes = _image_tensor_to_png_bytes(images[0])
image_url = _upload_image(api_key, png_bytes)
_log(log, f"Image upload success: {_truncate_url(image_url)}")
payload = {
"model": MODEL_NAME,
"input": {
"prompt": prompt,
"image_urls": [image_url],
"sound": sound,
"duration": duration,
},
}
_log(log, "Creating Kling 2.6 I2V task...")
start_time = time.time()
task_id, create_response_text = _create_kling_task(api_key, payload)
_log(log, f"createTask response (elapsed={time.time() - start_time:.1f}s): {create_response_text}")
_log(log, f"Task created with ID {task_id}. Polling for completion...")
record_data = _poll_task_until_complete(
api_key,
task_id,
poll_interval_s,
timeout_s,
log,
start_time,
)
result_urls = _extract_result_urls(record_data)
video_url = result_urls[0]
_log(log, f"Downloading video result from {video_url}...")
video_bytes = _download_video(video_url)
video_path = _write_video_to_temp_file(video_bytes)
_log(log, f"Video saved to {video_path}")
_log_remaining_credits(log, record_data, api_key, _log)
return video_path
+84
View File
@@ -1,3 +1,5 @@
import time
import torch
from .kie_api.auth import _load_api_key
@@ -20,7 +22,9 @@ from .kie_api.seedream45_edit import (
run_seedream45_edit,
)
from .kie_api.seedancev1pro_fast_i2v import KIE_SeedanceV1Pro_Fast_I2V
from .kie_api.kling26_i2v import DURATION_OPTIONS as KLING26_DURATION_OPTIONS, run_kling26_i2v
from .kie_api.grid import slice_grid_tensor
from .kie_api.http import TransientKieError
class KIE_GetRemainingCredits:
@@ -240,6 +244,84 @@ Outputs:
return (image_tensor,)
class KIE_Kling26_I2V:
HELP = """
KIE Kling 2.6 (Video)
Generate a short video clip from a prompt and a single input image using Kling 2.6.
Inputs:
- prompt: Text prompt (required)
- images: Source image batch (first image used)
- duration: 5s or 10s
- sound: Include audio in the output video
- poll_interval_s / timeout_s / log
- retry_on_fail / max_retries / retry_backoff_s
Outputs:
- STRING: Path to a temporary video file
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"prompt": ("STRING", {"multiline": True}),
"images": ("IMAGE",),
},
"optional": {
"duration": ("COMBO", {"options": KLING26_DURATION_OPTIONS, "default": "5"}),
"sound": ("BOOLEAN", {"default": False}),
"log": ("BOOLEAN", {"default": True}),
"poll_interval_s": ("FLOAT", {"default": 1.0, "min": 0.5, "max": 60.0, "step": 0.5}),
"timeout_s": ("INT", {"default": 600, "min": 1, "max": 3600, "step": 1}),
"retry_on_fail": ("BOOLEAN", {"default": True}),
"max_retries": ("INT", {"default": 2, "min": 0, "max": 10, "step": 1}),
"retry_backoff_s": ("FLOAT", {"default": 3.0, "min": 0.0, "max": 300.0, "step": 0.5}),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("video_path",)
FUNCTION = "generate"
CATEGORY = "kie/api"
def generate(
self,
prompt: str,
images: torch.Tensor,
duration: str = "5",
sound: bool = False,
log: bool = True,
poll_interval_s: float = 1.0,
timeout_s: int = 600,
retry_on_fail: bool = True,
max_retries: int = 2,
retry_backoff_s: float = 3.0,
):
attempts = max_retries + 1 if retry_on_fail else 1
attempts = max(attempts, 1)
backoff = retry_backoff_s if retry_backoff_s >= 0 else 0.0
for attempt in range(1, attempts + 1):
try:
video_path = run_kling26_i2v(
prompt=prompt,
images=images,
duration=duration,
sound=sound,
poll_interval_s=poll_interval_s,
timeout_s=timeout_s,
log=log,
)
return (video_path,)
except TransientKieError:
if not retry_on_fail or attempt >= attempts:
raise
_log(log, f"Retrying (attempt {attempt + 1}/{attempts}) after {backoff}s")
time.sleep(backoff)
class KIE_GridSlice:
HELP = """
KIE Grid Slice
@@ -308,6 +390,7 @@ NODE_CLASS_MAPPINGS = {
"KIE_Seedream45_TextToImage": KIE_Seedream45_TextToImage,
"KIE_Seedream45_Edit": KIE_Seedream45_Edit,
"KIE_SeedanceV1Pro_Fast_I2V": KIE_SeedanceV1Pro_Fast_I2V,
"KIE_Kling26_I2V": KIE_Kling26_I2V,
"KIE_GridSlice": KIE_GridSlice,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -316,5 +399,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"KIE_Seedream45_TextToImage": "KIE Seedream 4.5 Text-To-Image",
"KIE_Seedream45_Edit": "KIE Seedream 4.5 Edit",
"KIE_SeedanceV1Pro_Fast_I2V": "KIE Seedance V1 Pro Fast (I2V)",
"KIE_Kling26_I2V": "KIE Kling 2.6 (Video)",
"KIE_GridSlice": "KIE Grid Slice",
}
+29
View File
@@ -0,0 +1,29 @@
# KIE Kling 2.6 (Video)
## Overview
Generate a short video clip from a single input image plus a text prompt using the Kling 2.6 image-to-video model.
## Inputs
- prompt (STRING, multiline, required): The text prompt for the video.
- images (IMAGE, required): Source image batch; the first image is used.
- duration (COMBO, seconds, default: 5): Video length. Options: 5, 10.
- sound (BOOLEAN, default: false): Include audio in the output video.
- poll_interval_s (FLOAT, seconds, default: 1.0): How often to poll job status.
- timeout_s (INT, seconds, default: 600): Max wait time before timing out.
- log (BOOLEAN, default: true): Enable KIE console logs.
- retry_on_fail (BOOLEAN, default: true): Retry on transient API failures.
- max_retries (INT, default: 2): Number of retry attempts.
- retry_backoff_s (FLOAT, seconds, default: 3.0): Delay between retries.
## Outputs
- video_path (STRING): Local path to the generated video file.
## Examples
Prompt: "A small robot dances on a wooden desk under warm sunlight."
Duration: 5
Sound: false
## Troubleshooting
- Timeouts: Increase timeout_s or reduce duration to 5 seconds.
- Internal error / try later: Enable retries and increase retry_backoff_s.
- Insufficient credits: Check remaining credits and top up your KIE account.