사용 가이드
hiapi API에서 kling-3.0/motion-control로 숏폼 영상 만드는 방법
생성된 영상 속 캐릭터가 특정 동작을 하도록 만들려고 해 본 적이 있다면—"춤을 춰라"가 아니라 이 특정 클립 속의 바로 이 춤—보통의 선택지가 얼마나 형편없는지 알 것입니다. 수작업으로 프레임마다 로토스코핑하거나, 모션 모델을 다시 학습시키거나, 아니면 그냥 포기하고 텍스트 프롬프트가 주는 대로 받아들이는 것이죠. kling-3.0/motion-control은 이 모든 것을 건너뜁니다. 캐릭터 이미지 하나와 참조 영상 하나를 주면, 참조 영상의 동작과 표정을 당신의 캐릭터로 옮겨 줍니다—리깅도, 키프레임도, 모션 캡처 슈트도 필요 없습니다.
이 글은 실제 숏폼 영상 워크플로를 따라갑니다. 먼저 운전자 사진 한 장을 짧은 참조 클립으로 만들고, 그다음 그 클립으로 motion-control을 통해 완전히 다른 캐릭터 이미지를 구동합니다. 아래의 모든 요청은 hiapi의 /v1/tasks API에 대한 실제 호출이며, 모든 소재는 이 글을 작성하는 과정에서 생성되었고(벤더 데모 갤러리에서 빌려온 것은 아무것도 없습니다), 모든 가격은 hiapi의 가격 엔드포인트에서 실시간으로 가져온 것입니다.
kling-3.0/motion-control은 정확히 무엇을 하는가
이 모델은 두 개의 입력을 받습니다:
image_url—— 단일 캐릭터 초상화("대상"). 최종 출력에 누가 등장하는지를 결정합니다.video_url—— 모션 참조 클립, 3–30초. 그들이 무엇을 하는지를 결정합니다.
출력은 대상 캐릭터가 참조 영상의 동작과 얼굴 표정을 수행하는 영상이며, 720p 또는 1080p로 렌더링됩니다. 텍스트 프롬프트, 길이, 화면 비율은 받지 않습니다—출력 구도는 참조 클립을 그대로 따르고, 출력 길이도 입력 클립의 길이를 따릅니다(3초 참조로 3.03초 출력이 나왔습니다).
이렇게 입력이 두 개뿐인 좁은 계약이 바로 숏폼 콘텐츠에 유용한 이유입니다: 브랜드 마스코트, 제품 캐릭터, 스타일화된 아바타에 그럴듯한 연기를 입히기 위해 모션 캡처 장비가 필요 없습니다—당신이 원하는 동작을 하는 사람의 영상 아무거나 하나만 있으면 됩니다.
필요한 준비물
- hiapi API 키(
Authorization: Bearer <key>) - HTTPS로 공개 접근 가능한 캐릭터 이미지 한 장(대상이 아니라—당신의 드라이버 캐릭터)
- 애니메이션할 실제 대상이 될 두 번째 캐릭터 이미지
- 로컬에서 커버 프레임을 추출하거나 클립 길이를 확인하려면
ffmpeg/ffprobe, 이 글에서 한 방식과 동일
실제 데모: 하나의 동작 클립, 두 명의 다른 캐릭터
motion-control의 핵심은 참조 영상과 최종 캐릭터가 일치할 필요가 없다는 것입니다. 이를 증명하기 위해 이 데모는 세 가지 생성 단계를 사용합니다:
1. 운전자 초상화 한 장을 짧은 참조 클립으로 애니메이션화:

그 초상화는 grok-imagine-1.5/image-to-video를 통해 3초, 480p 동작 클립이 되었습니다—기성 클립을 찾는 대신 정지 이미지에서 참조 클립을 만드는 빠르고 저렴한 방법입니다:
2. 완전히 다른 대상 캐릭터—같은 동작, 전혀 다른 외형:

3. 둘 다 motion-control에 입력. 노점 주인이 배달원과 똑같은 몸 돌려 뒤돌아보는 동작을 수행합니다:
이것이 전체 워크플로입니다: 원하는 동작 클립을 생성하거나 구하고, motion-control을 완전히 무관한 캐릭터 이미지에 가리키면, 그 캐릭터가 해당 동작을 수행하는 결과를 얻습니다. 숏폼 파이프라인에서 이것이 의미하는 바는, 하나의 참조 동작 라이브러리로 무한한 수의 캐릭터를 구동할 수 있다는 것이며, 매번 다시 촬영하거나 참조 애니메이션을 다시 만들 필요가 없습니다.
최소 동작 요청(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"
}
}'
응답(작업 생성됨, 아직 처리 중):
{
"code": 0,
"data": {
"taskId": "tk-hiapi-01M4CWNSYA7RB637YJ2QZMHMMS",
"status": "pending"
},
"success": true
}
완료될 때까지 폴링:
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01M4CWNSYA7RB637YJ2QZMHMMS \
-H "Authorization: Bearer $HIAPI_API_KEY"
우리 실행에서는 3초 720p 클립이 처음부터 끝까지 약 2.3분 걸렸습니다(상태가 success로 전환되기 전에 handling을 십여 차례 반복했습니다)—폴링 루프를 설계할 때는 몇 초가 아니라 몇 분을 염두에 두세요. 최종 응답:
{
"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
}
그 output[0].url은 임시 링크입니다—expireAt은 Unix 타임스탬프이며, 테스트에서는 약 24시간 동안 유효했습니다. 즉시 다운로드해 다시 호스팅하세요; 게시하는 어떤 콘텐츠에도 이 링크를 직접 걸지 마세요.
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")
복잡할 것 없습니다—작업을 생성하고, 일정 간격으로 GET /v1/tasks/{taskId}를 폴링하고, success가 되는 순간 output[0].url을 다운로드한 뒤 임시 링크가 만료되기 전에 직접 다시 호스팅하세요.
motion-control이 실제로 검증하는 파라미터
스키마는 엄격합니다—이 세 필드 외의 어떤 것도 거부되므로, 시행착오로 알게 되기보다 미리 아는 게 유용합니다:
| 필드 | 필수 여부 | 설명 |
|---|---|---|
image_url |
예 | 공개 HTTPS URL, 대상 캐릭터 |
video_url |
예 | 공개 HTTPS URL, 3–30초 동작 참조 |
resolution |
아니오(기본값 있음, 하지만 설정할 가치 있음) | "720p" 또는 "1080p"—가격 등급도 이것으로 결정됨 |
다른 영상 모델에서 기대했을 법한 필드—duration, aspect_ratio, prompt—는 스키마 오류로 거부됩니다:
{
"code": 1,
"message": "input: Object { input } has unexpected additional properties: duration, aspect_ratio",
"success": false
}
이것은 의도된 설계입니다: 출력의 길이와 구도는 참조 영상에서 완전히 상속되므로 duration/aspect_ratio로 제어할 것이 없습니다. 더 길거나 다른 구도의 출력을 원한다면 요청을 수정하는 대신 보내기 전에 참조 클립을 자르거나 구도를 다시 잡으세요.
가격 책정: 요청당이 아니라 출력 초당 과금
hiapi의 가격 엔드포인트에서 직접 가져온 값:
| 해상도 | 가격 |
|---|---|
| 720p | $0.10 / 출력 초 |
| 1080p | $0.172 / 출력 초 |
과금은 실제 출력 길이(estimated_seconds)에 의해 결정되며, 이는 참조 클립 길이를 반영합니다—요청당 고정 요금이 아닙니다. 우리의 3초 참조는 720p에서 3.03초 출력을 생성했고 약 $0.30이 들었습니다. 10초 1080p 참조라면 약 $1.72에 가깝습니다. 콘텐츠 캘린더에서 대량으로 사용한다면, 실제로 조정할 수 있는 지렛대는 참조 클립 길이입니다: 더 짧은 참조는 비용이 낮으면서도 숏폼 포맷(Reels, TikTok, Shorts)에 필요한 온전한 동작 연기를 담아낼 수 있으며, 이런 포맷에서는 3–8초가 종종 전체 클립입니다.
프로덕션 고려 사항
- 드라이버 클립의 구도를 의식적으로 선택하세요. 출력은 참조 영상의 화면 비율, 카메라 거리, 리듬을 상속합니다—클로즈업 참조는 대상 캐릭터 이미지가 어떻게 잘렸든 클로즈업 출력을 유지합니다.
- 뚜렷한 표정이 미묘한 표정보다 더 잘 전이됩니다. 참조의 명확한 몸 돌리기, 손 흔들기, 고개 갸우뚱은 대상 캐릭터에서 안정적으로 나타납니다; 아주 미묘하고 자연스러운 미세 표정은 모델이 인식하고 전이하기 더 어렵습니다.
- 하나의 참조 클립을 많은 캐릭터에 재사용하세요.
video_url과image_url이 완전히 독립적이므로, 콘텐츠 파이프라인에서 가장 효율적인 패턴은 작은 참조 동작 라이브러리를 먼저 구축한 뒤 같은 클립으로 여러 다른 캐릭터 이미지를 실행하는 것입니다. - 임시 출력 URL은 유효 기간이 짧습니다.
expireAt은 보통 하루 정도입니다—다운로드를 나중으로 미루지 말고 즉시 다운로드해 다시 호스팅하세요. - 처리는 즉시가 아닙니다. 이 테스트에서 3초 720p 클립은 처음부터 끝까지 2분 넘게 걸렸습니다; 폴링 루프와 다운스트림 자동화는 텍스트-이미지 호출에서 흔한 초 단위가 아니라 분 단위를 기준으로 계획하세요.
관련 항목
참조 클립과 짝지을 캐릭터가 있나요? 가격 페이지에서 키를 받은 뒤, 위 curl 요청을 당신의 image_url/video_url로 가리키세요—위의 전체 루프를 그대로 복사-붙여넣기할 수 있습니다.
자주 묻는 질문
어떤 영상이든 동작 참조로 사용할 수 있나요? 명확한 사람(또는 사람 유사) 출연자가 있고, HTTPS로 공개 접근 가능하며 3–30초 길이라면 무엇이든 됩니다. 대상 캐릭터가 포함될 필요는 없습니다—그것이 바로 이 모델의 존재 이유입니다.
출력에 참조 영상의 배경이 유지되나요? 아니요—캐릭터의 외형은 대상 이미지가 암시하는 환경을 포함해 이어집니다; 참조 영상은 동작과 표정을 제공할 뿐 장면 내용을 제공하지 않습니다.
왜 요청이 "unexpected additional properties"로 거부되나요?
스키마는 image_url, video_url, resolution만 허용합니다. duration, aspect_ratio, prompt 같은 필드는 이 모델의 입력이 아니며 즉시 400을 반환합니다—payload에서 삭제하세요.
motion-control 작업은 얼마나 걸리나요?
클립당 몇 분을 잡으세요. 우리의 3초 720p 예시는 작업 생성부터 다운로드 가능한 success 출력까지 약 2.3분 걸렸습니다.
가격과 별개로 출력 해상도를 제어할 수 있나요?
아니요—resolution은 출력 품질 설정이자 가격 등급 선택자입니다: "720p"는 출력 초당 $0.10, "1080p"는 출력 초당 $0.172로 과금됩니다.
관련 글
모든 아티클 보기 →-
사용 가이드
seedream-5.0-pro/image-to-image 시작 가이드: 기능, 가격 및 연동 핵심 포인트
ByteDance 이미지 편집 모델의 기능 경계, 과금 방식 및 엔지니어링 연동 실무
-
사용 가이드
seedream-5.0-pro 텍스트-이미지 생성 입문 가이드: 능력 경계, API 연동 및 비용 관리
개발자를 위한 실무 관점: 파라미터 핵심부터 장당 $0.05 비용 추정까지
-
사용 가이드
Hailuo 2.3 Fast 이미지-투-비디오 입문 가이드: 성능 범위, 가격 및 연동 실무
개발자를 위한 MiniMax 이미지-투-비디오 모델 선택과 연동 핵심 포인트