# 1. on a dubbed project: confirm the video has a face (runs once, usually automatically)
curl https://api.rask.ai/v2/projects/$ID/lipsync \
-H "Authorization: Bearer $TOKEN"
# "check_face_task_status": "done", "video_has_face": true
# 2. preview one free minute of lip-sync
curl -X PUT https://api.rask.ai/v2/projects/$ID/lipsync \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"is_multiple_speakers": true, "is_free_lipsync": true}'
# 3. lip-sync the full video - billed separately from dubbing
curl -X PUT https://api.rask.ai/v2/projects/$ID/lipsync \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"is_multiple_speakers": true, "is_free_lipsync": false}'# Poll until lipsync_task_status is done, then download lipsync_result_path
while :; do
curl -s https://api.rask.ai/v2/projects/$ID/lipsync -H "Authorization: Bearer $TOKEN" \
| jq '{lipsync_task_status, lipsync_task_progress, tasks_in_lipsync_queue}'
sleep 15
done동영상을 업로드하거나 공개 URL을 입력하고, 목표 언어로 프로젝트를 만든 뒤 병합이 완료될 때까지 기다리세요. 입모양 싱크에는 해당 프로젝트의 번역된 동영상이 필요합니다.
얼굴 확인 작업을 통해 영상에 최소 한 명의 얼굴이 있는지 확인합니다. 보통 자동으로 시작되지만, 시작되지 않았다면 프로젝트에서 직접 한 번 실행해 주세요.
입모양 싱크 작업을 실행하고 0부터 100까지 진행되는 상태를 확인한 다음, 결과 경로에서 영상을 다운로드하세요.
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas
PROJECT_ID = "..." # a project with status merging_done
async def main():
client = clients.RaskSDKClient(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
info = await client.get_lipsync_info(project_id=PROJECT_ID)
if info.check_face_task_status is not enums.LipsyncStatus.DONE:
await client.run_check_face_task(project_id=PROJECT_ID)
while (info := await client.get_lipsync_info(project_id=PROJECT_ID)).check_face_task_status is not enums.LipsyncStatus.DONE:
await asyncio.sleep(10)
if not info.video_has_face:
raise SystemExit("No face found - lip-sync is not available for this video")
await client.run_lipsync_task(project_id=PROJECT_ID,
data=schemas.LipsyncTaskData(is_multiple_speakers=True, is_free_lipsync=False))
while (info := await client.get_lipsync_info(project_id=PROJECT_ID)).lipsync_task_status is not enums.LipsyncStatus.DONE:
print(info.lipsync_task_progress, info.tasks_in_lipsync_queue)
await asyncio.sleep(15)
print(info.lipsync_result_path)
asyncio.run(main())import time, requests
AUTH = "https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token"
URL = f"https://api.rask.ai/v2/projects/{PROJECT_ID}" # a dubbed project
token = requests.post(AUTH, auth=(CLIENT_ID, CLIENT_SECRET),
data={"grant_type": "client_credentials"}).json()["access_token"]
h = {"Authorization": f"Bearer {token}"}
info = requests.get(f"{URL}/lipsync", headers=h).json()
if info["check_face_task_status"] != "done":
requests.put(f"{URL}/check_face", headers=h)
while (info := requests.get(f"{URL}/lipsync", headers=h).json())["check_face_task_status"] != "done":
time.sleep(10)
assert info["video_has_face"], "No face found"
requests.put(f"{URL}/lipsync", headers=h,
json={"is_multiple_speakers": True, "is_free_lipsync": False})
while (info := requests.get(f"{URL}/lipsync", headers=h).json())["lipsync_task_status"] not in ("done", "failed"):
time.sleep(15)
print(info["lipsync_task_status"], info["lipsync_result_path"])// no dependencies, Node 18+ global fetch - PROJECT_ID is a dubbed project
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const auth = await fetch('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token', {
method: 'POST',
headers: { Authorization: 'Basic ' + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`) },
body: new URLSearchParams({ grant_type: 'client_credentials' }),
}).then((r) => r.json());
const h = { Authorization: `Bearer ${auth.access_token}`, 'Content-Type': 'application/json' };
const url = `https://api.rask.ai/v2/projects/${PROJECT_ID}`;
const info = () => fetch(`${url}/lipsync`, { headers: h }).then((r) => r.json());
let i = await info();
if (i.check_face_task_status !== 'done') {
await fetch(`${url}/check_face`, { method: 'PUT', headers: h });
while ((i = await info()).check_face_task_status !== 'done') await sleep(10000);
}
if (!i.video_has_face) throw new Error('No face found');
await fetch(`${url}/lipsync`, {
method: 'PUT', headers: h,
body: JSON.stringify({ is_multiple_speakers: true, is_free_lipsync: false }),
});
while (!['done', 'failed'].includes((i = await info()).lipsync_task_status)) {
console.log(i.lipsync_task_progress, i.tasks_in_lipsync_queue);
await sleep(15000);
}
console.log(i.lipsync_result_path);# 1. token (valid 1 hour - cache and reuse it)
TOKEN=$(curl -s -X POST https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" -d "grant_type=client_credentials" | jq -r .access_token)
# 2. face check on the dubbed project - start it only if it has not run yet
curl -s https://api.rask.ai/v2/projects/$ID/lipsync -H "Authorization: Bearer $TOKEN" \
| jq '{check_face_task_status, video_has_face}'
curl -s -X PUT https://api.rask.ai/v2/projects/$ID/check_face -H "Authorization: Bearer $TOKEN"
# 3. run lip-sync (set is_free_lipsync to true for the free preview minute)
curl -s -X PUT https://api.rask.ai/v2/projects/$ID/lipsync \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"is_multiple_speakers": true, "is_free_lipsync": false}'
# 4. follow progress, then download the result
curl -s https://api.rask.ai/v2/projects/$ID/lipsync -H "Authorization: Bearer $TOKEN" \
| jq '{lipsync_task_status, lipsync_task_progress, lipsync_result_path}'<?php
use GuzzleHttp\Client;
$http = new Client(['base_uri' => 'https://api.rask.ai']);
$json = fn($r) => json_decode($r->getBody(), true);
$auth = $json((new Client)->post('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
['auth' => [$clientId, $clientSecret], 'form_params' => ['grant_type' => 'client_credentials']]));
$h = ['Authorization' => 'Bearer ' . $auth['access_token']];
$info = fn() => $json($http->get("/v2/projects/$projectId/lipsync", ['headers' => $h]));
$i = $info();
if ($i['check_face_task_status'] !== 'done') {
$http->put("/v2/projects/$projectId/check_face", ['headers' => $h]);
while (($i = $info())['check_face_task_status'] !== 'done') sleep(10);
}
if (!$i['video_has_face']) exit('No face found');
$http->put("/v2/projects/$projectId/lipsync", ['headers' => $h,
'json' => ['is_multiple_speakers' => true, 'is_free_lipsync' => false]]);
while (!in_array(($i = $info())['lipsync_task_status'], ['done', 'failed'])) sleep(15);
echo $i['lipsync_result_path'];check face check_face_task_status done video_has_face true
queued lipsync_task_status started tasks_in_lipsync_queue 2
processing lipsync_task_progress 0 → 50 → 100
complete lipsync_task_status done
lipsync_result_path https://...

es-mx 및 es-es 지원합니다. 프로젝트는 glossary_version을 기록하므로, 나중에 수정해도 완료된 작업이 예기치 않게 변경되지 않습니다.네. Rask 립싱크 API는 프로젝트에서 더빙된 모든 영상에 적용할 수 있습니다. 영상에 얼굴이 나오는지 확인한 후 립싱크 작업을 시작하고, 작업이 완료되면 립싱크가 적용된 영상을 다운로드하세요. 인증에는 OAuth 2.0 클라이언트 자격 증명이 사용되므로, 다른 Rask API와 동일한 방식으로 연동할 수 있습니다.
립싱크는 번역된 영상에 적용됩니다. 먼저 프로젝트를 생성하여 더빙한 후, 프로젝트에 번역된 영상 링크가 생기고 상태가 merging_done으로 표시되면 립싱크를 시작하세요.
립싱크에는 프로젝트의 더빙된 오디오가 사용됩니다. 원하는 문구를 사용하려면 번역된 텍스트를 수정하거나 내 .srt 파일로 자막을 만든 후 프로젝트를 다시 더빙하고, 새 버전에서 립싱크를 실행하세요.
Rask는 입력한 영상에 등장하는 실제 인물의 실제 촬영본을 립싱크합니다. 이미지나 텍스트 프롬프트로 말하는 아바타, 디지털 휴먼, AI 영상을 생성하는 것은 다른 제품 카테고리이므로, 해당 기능에는 AI 영상 제작 툴이 더 적합합니다.
말하는 사람의 얼굴이 선명하게 보이고, 조명이 좋으며, 입 모양이 가려지지 않은 영상을 사용하세요. 마이크, 손, 자막 등으로 입술을 가리거나 얼굴이 측면을 향하는 것은 피하세요. 얼굴 감지 기능을 통해 얼굴이 있는지 확인할 수 있으며, 미리보기를 통해 내 영상에 적용된 결과를 확인해 볼 수 있습니다.
립싱크는 더빙과 별개로 전체 영상 생성 시마다 건별로 청구됩니다. 수정 후 새로운 립싱크 버전을 생성하는 경우 립싱크 요금이 다시 청구됩니다.
네. 모든 계정의 무료 크레딧에 입모양 맞춤 1분이 포함되어 있습니다. is_free_lipsync 값을 true로 설정하여 작업을 실행하면 동영상 1분의 입모양을 맞추고 확인할 수 있습니다. 크레딧 조회 API에서는 이를 lipsync_free_minutes로 표시합니다.
네. 인터뷰나 패널 토론처럼 화면에 여러 얼굴이 동시에 나올 수 있는 경우 is_multiple_speakers 값을 true로 설정하세요. 영상에 항상 한 번에 한 사람의 얼굴만 나오는 경우, false로 설정하면 처리 속도가 빨라집니다.
GET /v2/projects/{id}/lipsync를 호출하세요. 응답에서 lipsync_task_status는 started에서 done 또는 failed로 변경되고, lipsync_task_progress는 0에서 100까지 올라가며, tasks_in_lipsync_queue는 내 앞에 대기 중인 작업 수가 몇 개인지를 보여줍니다.
처리 시간은 동영상의 길이와 입모양 맞춤 대기열 상태에 따라 다릅니다. 대기열 순서와 진행률 값을 통해 사용자에게 작업이 어디쯤 진행되었는지 정확하게 보여줄 수 있습니다.
입모양 맞춤은 더빙된 버전별로 한 번씩 생성됩니다. 텍스트, 시간, 화자, 목소리를 변경한 후에는 프로젝트를 다시 더빙하고, merging_done이 될 때까지 기다린 다음 입모양 맞춤을 다시 실행하세요. 새로운 입모양 맞춤 생성에는 비용이 따로 청구됩니다. 이미 완료된 얼굴 검사는 다시 실행할 필요가 없습니다.
check_face_task_status나 lipsync_task_status가 실패(failed)로 표시되면 project_id와 함께 [email protected]로 문의해 주세요. 담당 팀에서 확인해 드리겠습니다.
유료 플랜에는 API 이용이 포함되어 있습니다. 앱에서 클라이언트 ID와 시크릿을 생성한 후 바로 API를 호출하실 수 있습니다. 기업용 조건, 대량 이용 할인, 맞춤 언어 지원은 저희 팀으로 문의해 주세요.