Documentos en ai-videos/ · generación de video con Kling API (image2video, modelo kling-v1-6)
arm-liquid-transition.md · Script: generate_arm_transition.py
the person's arm and hand gradually transform into flowing blue liquid, skin morphs into smooth glossy electric blue liquid with water-like ripples, droplets and surface highlights, photorealistic, same lighting, same tiled floor background, same camera angle and framing, only the arm changes, fluid dynamics, cinematic, 8K hyperrealistic
~/Movies/arm-liquid-transition/arm_to_liquid.mp4
(full: arm_to_liquid_full.mp4)
arm-fire-transition.md · Script: generate_arm_fire_transition.py
the person's arm and hand gradually transform into intense hyperrealistic fire, the blue liquid skin ignites and turns into bright orange and yellow flames with a white-hot core, glowing embers, heat distortion, sparks flying, smoke rising, photorealistic, same lighting, same tiled floor background, same camera angle and framing, only the arm changes, cinematic, 8K hyperrealistic fire physics
~/Movies/arm-fire-transition/arm_to_fire.mp4
arm-fire-to-normal-transition.md · Script: generate_arm_fire_to_normal_transition.py
the intense fire engulfing the person's arm and hand gradually extinguishes hyperrealistically, flames shrink and die out, embers cooling and fading, smoke dissipating, the burning arm slowly reveals normal human skin underneath, the hand rotates and opens from a closed fist to a relaxed open hand, photorealistic, same lighting, same tiled floor background, same camera angle and framing, cinematic, 8K hyperrealistic
~/Movies/arm-fire-to-normal-transition/arm_fire_to_normal.mp4
arm-liquid-transition.md · Script: generate_arm_transition.pyimport os
import time
import base64
import subprocess
import requests
import jwt # pip install PyJWT
ACCESS_KEY = os.getenv("KLING_ACCESS_KEY")
SECRET_KEY = os.getenv("KLING_SECRET_KEY")
BASE_URL = "https://api.klingai.com"
START_IMAGE = "inicio.jpeg"
END_IMAGE = "paso2 - agua.png"
OUTPUT_DIR = os.path.expanduser("~/Movies/arm-liquid-transition")
TARGET_DURATION = 3.5 # segundos, recorte final con ffmpeg
def get_token() -> str:
payload = {
"iss": ACCESS_KEY,
"exp": int(time.time()) + 1800,
"nbf": int(time.time()) - 5,
}
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
def to_base64(path: str) -> str:
with open(path, "rb") as f:
return base64.b64encode(f.read()).decode()
def submit(start: str, end: str, prompt: str) -> str:
headers = {
"Authorization": f"Bearer {get_token()}",
"Content-Type": "application/json",
}
payload = {
"model_name": "kling-v1-6",
"image": to_base64(start),
"image_tail": to_base64(end),
"prompt": prompt,
"negative_prompt": (
"blurry, low quality, artifacts, unnatural, body distortion outside "
"the arm, face changes, background changes, camera movement"
),
"cfg_scale": 0.8,
"mode": "pro",
"duration": "5",
}
resp = requests.post(f"{BASE_URL}/v1/videos/image2video", json=payload, headers=headers)
resp.raise_for_status()
task_id = resp.json()["data"]["task_id"]
print(f"Task: {task_id}")
return task_id
def poll(task_id: str, timeout: int = 300) -> str:
headers = {"Authorization": f"Bearer {get_token()}"}
deadline = time.time() + timeout
while time.time() < deadline:
resp = requests.get(
f"{BASE_URL}/v1/videos/image2video/{task_id}",
headers=headers,
)
resp.raise_for_status()
result = resp.json()["data"]
status = result["task_status"]
print(f" {status}...")
if status == "succeed":
return result["task_result"]["videos"][0]["url"]
if status == "failed":
raise RuntimeError(f"Failed: {result}")
time.sleep(10)
raise TimeoutError("Timed out")
def download(url: str, path: str):
r = requests.get(url, stream=True)
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(8192):
f.write(chunk)
print(f"Saved: {path}")
def trim(input_path: str, output_path: str, duration: float):
subprocess.run(
[
"ffmpeg", "-y", "-i", input_path,
"-t", str(duration),
"-c:v", "libx264", "-c:a", "aac",
output_path,
],
check=True,
)
print(f"Trimmed: {output_path}")
if __name__ == "__main__":
os.makedirs(OUTPUT_DIR, exist_ok=True)
prompt = (
"the person's arm and hand gradually transform into flowing blue liquid, "
"skin morphs into smooth glossy electric blue liquid with water-like "
"ripples, droplets and surface highlights, photorealistic, same lighting, "
"same tiled floor background, same camera angle and framing, "
"only the arm changes, fluid dynamics, cinematic, 8K hyperrealistic"
)
task_id = submit(START_IMAGE, END_IMAGE, prompt)
video_url = poll(task_id)
full_output = os.path.join(OUTPUT_DIR, "arm_to_liquid_full.mp4")
download(video_url, full_output)
trimmed_output = os.path.join(OUTPUT_DIR, "arm_to_liquid.mp4")
trim(full_output, trimmed_output, TARGET_DURATION)
print(f"\nDone: {trimmed_output}")