Guía de uso
Cómo crear videos cortos con kling-3.0/motion-control en la API de hiapi
Si alguna vez has intentado que un personaje en un video generado haga un movimiento concreto —no "bailar", sino este baile concreto de este clip concreto— sabes que las opciones habituales son malas: rotoscopiar fotograma a fotograma a mano, reentrenar un modelo de movimiento o simplemente rendirte y aceptar lo que te dé el prompt de texto. kling-3.0/motion-control se salta todo eso. Le das una imagen de un personaje y un video de referencia, y transfiere el movimiento y las expresiones de la referencia a tu personaje: sin rigging esquelético, sin keyframes, sin traje de captura de movimiento.
Este artículo recorre un flujo de trabajo real de video corto: primero convertimos la foto de un repartidor en un breve clip de referencia y luego usamos ese clip para impulsar, mediante motion-control, la imagen de un personaje completamente distinto. Cada petición que aparece abajo es una llamada real a la API /v1/tasks de hiapi, cada recurso se generó mientras se escribía este artículo (no se tomó nada prestado de la galería de demostraciones del proveedor) y cada precio se obtuvo en tiempo real del endpoint de precios de hiapi.
Qué hace exactamente kling-3.0/motion-control
El modelo recibe dos entradas:
image_url— un único retrato de personaje (el "objetivo"). Esto determina quién aparece en la salida.video_url— el clip de referencia de movimiento, de 3 a 30 segundos. Esto determina qué hace.
La salida es un video en el que el personaje objetivo ejecuta los movimientos y las expresiones faciales del video de referencia, renderizado a 720p o 1080p. No acepta prompt de texto, duración ni relación de aspecto: la composición de la salida sigue directamente al clip de referencia y la longitud de la salida sigue a la del clip de entrada (nuestra referencia de 3 segundos devolvió una salida de 3,03 segundos).
Ese contrato estrecho de solo dos entradas es precisamente lo que lo hace útil para contenido de video corto: no necesitas equipo de captura de movimiento para dar una actuación creíble a la mascota de una marca, a un personaje de producto o a un avatar estilizado; solo necesitas cualquier video de una persona haciendo el movimiento que quieres.
Qué necesitas preparar
- Una clave de API de hiapi (
Authorization: Bearer <key>) - Una imagen de personaje accesible públicamente por HTTPS (no es tu objetivo: es tu personaje conductor)
- Una segunda imagen de personaje, que será el objetivo real que quieres animar
ffmpeg/ffprobesi quieres extraer fotogramas de portada o comprobar la duración de los clips en local, tal como se hace en este artículo
Demostración real: un clip de movimiento, dos personajes distintos
La clave de motion-control es que el video de referencia y el personaje final no tienen por qué coincidir. Para demostrarlo, esta demo usa tres pasos de generación:
1. Un retrato de repartidor, animado hasta convertirlo en un breve clip de referencia:

Ese retrato se convirtió en un clip de acción de 3 segundos y 480p mediante grok-imagine-1.5/image-to-video: una forma rápida y barata de fabricar un clip de referencia a partir de una imagen estática, en lugar de buscar un clip ya existente:
2. Un personaje objetivo completamente distinto: el mismo movimiento, un aspecto totalmente diferente:

3. Introduce ambos en motion-control. El vendedor ejecuta exactamente el mismo giro y mirada por encima del hombro que el repartidor:
Ese es todo el flujo de trabajo: genera (u obtén) cualquier clip de movimiento que te guste, apunta motion-control a la imagen de un personaje completamente ajeno y consigue que ese personaje ejecute el movimiento. Para una cadena de producción de video corto, esto significa que una biblioteca de movimientos de referencia puede impulsar un número ilimitado de personajes sin volver a rodar ni rehacer la animación de referencia cada vez.
Petición mínima funcional (curl)
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0/motion-control",
"input": {
"image_url": "https://static.hiapi.ai/blog/kling-3-0-motion-control-short-form-video/target-character.png",
"video_url": "https://static.hiapi.ai/blog/kling-3-0-motion-control-short-form-video/motion-reference.mp4",
"resolution": "720p"
}
}'
Respuesta (tarea creada, aún en proceso):
{
"code": 0,
"data": {
"taskId": "tk-hiapi-01M4CWNSYA7RB637YJ2QZMHMMS",
"status": "pending"
},
"success": true
}
Consulta repetidamente hasta que termine:
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01M4CWNSYA7RB637YJ2QZMHMMS \
-H "Authorization: Bearer $HIAPI_API_KEY"
En nuestra ejecución, un clip de 3 segundos en 720p tardó aproximadamente 2,3 minutos de principio a fin (el estado pasó por handling unas diez veces antes de cambiar a success): al diseñar un bucle de consulta, reserva minutos, no segundos. Respuesta final:
{
"code": 0,
"data": {
"taskId": "tk-hiapi-01M4CWNSYA7RB637YJ2QZMHMMS",
"status": "success",
"output": [
{
"type": "video",
"url": "https://temp.hiapi.ai/7c6ttvrbpt/01M4CWNSYA7RB637YJ2QZMHMMS-0.mp4",
"storage": "temp",
"expireAt": 1792039027
}
]
},
"success": true
}
Ese output[0].url es un enlace temporal: expireAt es una marca de tiempo Unix que, en nuestras pruebas, tiene una validez de unas 24 horas. Descárgalo y vuelve a alojarlo de inmediato; no enlaces directamente a él desde nada que publiques.
El mismo flujo en Python
import os
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
def create_motion_control_task(image_url: str, video_url: str, resolution: str = "720p") -> str:
resp = requests.post(
API_BASE,
headers=HEADERS,
json={
"model": "kling-3.0/motion-control",
"input": {
"image_url": image_url,
"video_url": video_url,
"resolution": resolution,
},
},
timeout=60,
)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_for_result(task_id: str, timeout_s: int = 600, poll_every: int = 10) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
resp = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
task = resp.json()["data"]
if task["status"] == "success":
return task["output"][0]["url"]
if task["status"] == "fail":
raise RuntimeError(task.get("error"))
time.sleep(poll_every)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = create_motion_control_task(
image_url="https://your-cdn.example.com/target-character.png",
video_url="https://your-cdn.example.com/motion-reference.mp4",
resolution="720p",
)
output_url = wait_for_result(task_id)
video_bytes = requests.get(output_url, timeout=120).content
with open("motion-control-output.mp4", "wb") as f:
f.write(video_bytes)
print(f"saved {len(video_bytes)} bytes")
No tiene nada de complicado: crea la tarea, consulta GET /v1/tasks/{taskId} a intervalos regulares, descarga output[0].url en el momento en que pase a success y vuelve a alojarlo tú mismo antes de que caduque el enlace temporal.
Los parámetros que motion-control valida realmente
El esquema es estricto: cualquier cosa fuera de estos tres campos se rechaza, y conviene saberlo de antemano en lugar de descubrirlo a base de prueba y error:
| Campo | ¿Obligatorio? | Descripción |
|---|---|---|
image_url |
Sí | URL HTTPS pública, personaje objetivo |
video_url |
Sí | URL HTTPS pública, referencia de movimiento de 3 a 30 segundos |
resolution |
No (tiene valor por defecto, pero conviene establecerse) | "720p" o "1080p": también determina el tramo de precio |
Los campos que podrías esperar de otros modelos de video —duration, aspect_ratio, prompt— se rechazan con un error de esquema:
{
"code": 1,
"message": "input: Object { input } has unexpected additional properties: duration, aspect_ratio",
"success": false
}
Es así por diseño: la duración y la composición de la salida se heredan por completo del video de referencia, así que duration/aspect_ratio no tienen nada que controlar. Si quieres una salida más larga o con otra composición, recorta o reencuadra el clip de referencia antes de enviarlo, en lugar de modificar la petición.
Precios: se cobra por segundo de salida, no por petición
Directamente del endpoint de precios de hiapi:
| Resolución | Precio |
|---|---|
| 720p | $0.10 / segundo de salida |
| 1080p | $0.172 / segundo de salida |
El cobro lo determina la duración real de la salida (estimated_seconds), que refleja la longitud de tu clip de referencia, y no una tarifa fija por petición. Nuestra referencia de 3 segundos produjo una salida de 3,03 segundos en 720p y costó aproximadamente $0.30. Un clip de referencia de 10 segundos en 1080p se acerca a $1.72. Si lo vas a usar en serie dentro de un calendario de contenidos, la palanca realmente ajustable es la longitud del clip de referencia: los clips más cortos cuestan menos y siguen bastando para dar una actuación completa en formatos de video corto (Reels, TikTok, Shorts), donde 3–8 segundos suelen ser el clip entero.
Consideraciones para producción
- Elige conscientemente la composición del clip conductor. La salida hereda la relación de aspecto, la distancia de cámara y el ritmo del video de referencia: una referencia en primer plano dará una salida en primer plano, independientemente de cómo esté recortada la imagen de tu personaje objetivo.
- Las expresiones claras se transfieren mejor que las sutiles. Un giro, un saludo o una inclinación de cabeza claros en la referencia se reproducen de forma fiable en el personaje objetivo; las microexpresiones muy sutiles y naturales son más difíciles de que el modelo las detecte y las transfiera.
- Reutiliza un solo clip de referencia con muchos personajes. Como
video_urleimage_urlson totalmente independientes, el patrón más eficiente en una cadena de contenido es: crear primero una pequeña biblioteca de movimientos de referencia y luego ejecutar muchas imágenes de personajes distintos con el mismo clip. - Las URL de salida temporales caducan pronto.
expireAtsuele ser de un día aproximadamente: descarga y vuelve a alojar de inmediato, en lugar de dejar la descarga para más tarde. - El procesamiento no es instantáneo. En esta prueba, un clip de 3 segundos en 720p tardó más de dos minutos de principio a fin; planifica tu bucle de consulta y cualquier automatización posterior en torno a minutos (no a los segundos habituales de las llamadas de texto a imagen).
Contenido relacionado
¿Tienes un clip de referencia y un personaje que quieres emparejar? Consigue una clave en la página de precios y apunta la petición curl de arriba a tus propios image_url/video_url: todo el bucle anterior se puede copiar y pegar tal cual.
Preguntas frecuentes
¿Puedo usar cualquier video como referencia de movimiento? Sirve cualquier video con una persona (o un ser humanoide) que actúe con claridad, siempre que sea accesible públicamente por HTTPS y dure entre 3 y 30 segundos. No hace falta que contenga tu personaje objetivo: precisamente de eso trata el modelo.
¿La salida conserva el fondo del video de referencia? No: se mantiene el aspecto del personaje, incluido el entorno que sugiere la imagen objetivo; el video de referencia aporta el movimiento y las expresiones, no el contenido de la escena.
¿Por qué me rechazan la petición con «unexpected additional properties»?
El esquema solo acepta image_url, video_url y resolution. Campos como duration, aspect_ratio o prompt no forman parte de las entradas de este modelo y devuelven un 400 de inmediato: elimínalos del payload.
¿Cuánto tarda una tarea de motion-control?
Reserva varios minutos por clip. Nuestro ejemplo de 3 segundos en 720p tardó unos 2,3 minutos desde la creación de la tarea hasta tener una salida success descargable.
¿Puedo controlar la resolución de salida de forma independiente al precio?
No: resolution es a la vez el ajuste de calidad de salida y el selector del tramo de precio: "720p" se factura a $0.10 por segundo de salida y "1080p" a $0.172 por segundo de salida.
Artículos relacionados
Ver todos los artículos →-
Guía de uso
seedream-5.0-pro/image-to-image: guía de introducción — capacidades, precios y puntos clave de integración
Límites de capacidad, modelo de facturación y prácticas de integración técnica del modelo de edición de imágenes de ByteDance
-
Guía de uso
Guía de inicio de seedream-5.0-pro texto a imagen: límites de capacidad, integración de API y control de costes
Perspectiva práctica para desarrolladores: desde los puntos clave de los parámetros hasta la estimación de coste de $0.05 por imagen
-
Guía de uso
Guía de inicio de Hailuo 2.3 Fast de imagen a video: límites de capacidad, precios e integración práctica
Claves de selección e integración del modelo MiniMax de imagen a video para desarrolladores