# 1. create the dub - each speaker gets an Instant Voice Clone by default
curl -X POST https://api.rask.ai/v2/projects \
-H "Authorization: Bearer $TOKEN" \
-d '{"video_id": "b8f7835d-e8c9-4ff4-8e34-5c336d818319", "dst_lang": "es-mx"}'
# 2. list the voices available in this project
curl https://api.rask.ai/v2/projects/$ID/voices \
-H "Authorization: Bearer $TOKEN"
# "label": "Voice Clone", "gender": "auto" instant clone
# "label": "Maria Lopez", "sample_src": "https://..." your custom clone
# 3. assign your custom clone - include every speaker in the map
curl -X PATCH https://api.rask.ai/v2/projects/$ID \
-H "Authorization: Bearer $TOKEN" \
-d '{"voice": {"SPEAKER_00": "<custom_voice_id>", "SPEAKER_01": "<voice_id>"}}'# 4. re-dub with the new voices, then poll until merging_done
curl -X POST https://api.rask.ai/v2/projects/$ID/generate \
-H "Authorization: Bearer $TOKEN"
while :; do
curl -s https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN" | jq .status
sleep 10
done파일을 여러 부분으로 나누어 전송하거나 YouTube, Google Drive, S3, Vimeo 등의 링크 또는 직접 URL을 입력하세요. 이 동영상의 음성은 간편 목소리 복제의 기준이 되는 목소리 샘플이 됩니다.
미디어 ID를 video_id로 입력하고 목표 언어를 설정하세요. 감지된 화자마다 지원되는 언어로 간편 목소리 복제가 생성되며 즉시 더빙이 시작됩니다.
프로젝트의 목소리 목록을 확인하고, 원하는 화자에게 맞춤형 복제 목소리나 기본 설정 목소리를 지정한 다음 /generate를 호출하고 더빙이 완료되면 파일을 다운로드하세요.
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas
async def wait(client, job):
while job.status is not enums.ProjectStatus.MERGING_DONE:
await asyncio.sleep(10)
job = await client.get_project(project_id=job.id)
return job
async def main():
client = clients.RaskSDKClient(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
video = await client.create_media_link(data=schemas.MediaCreateLink(link="https://youtu.be/..."))
while video.status is not enums.MediaStatus.READY:
await asyncio.sleep(5)
video = await client.get_media(media_id=video.id)
# first dub: every speaker gets an Instant Voice Clone
job = await wait(client, await client.create_project(
data=schemas.ProjectCreate(video_id=video.id, dst_lang="es-mx")))
# assign a custom clone to SPEAKER_00, keep the other speakers as they are
voices = await client.get_project_voices(project_id=job.id)
custom = next(v for v in voices if v.label == "Maria Lopez")
voice_map = {**job.voice, "SPEAKER_00": custom.id}
await client.patch_project(project_id=job.id, data=schemas.ProjectPatch(voice=voice_map))
job = await wait(client, await client.generate_project(project_id=job.id))
print(job.translated_video, job.voiceover)
asyncio.run(main())import time, requests
AUTH = "https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token"
API = "https://api.rask.ai"
token = requests.post(AUTH, auth=(CLIENT_ID, CLIENT_SECRET),
data={"grant_type": "client_credentials"}).json()["access_token"]
h = {"Authorization": f"Bearer {token}"}
def wait(pid):
while (p := requests.get(f"{API}/v2/projects/{pid}", headers=h).json())["status"] != "merging_done":
time.sleep(10)
return p
video = requests.post(f"{API}/api/library/v1/media/link", headers=h, json={"link": "https://youtu.be/..."}).json()
while video["status"] != "ready":
time.sleep(5)
video = requests.get(f"{API}/api/library/v1/media/{video['id']}", headers=h).json()
pid = requests.post(f"{API}/v2/projects", headers=h,
json={"video_id": video["id"], "dst_lang": "es-mx"}).json()["id"]
project = wait(pid)
voices = requests.get(f"{API}/v2/projects/{pid}/voices", headers=h).json()
custom = next(v for v in voices if v["label"] == "Maria Lopez")
voice_map = {**project["voice"], "SPEAKER_00": custom["id"]} # every speaker stays in the map
requests.patch(f"{API}/v2/projects/{pid}", headers=h, json={"voice": voice_map})
requests.post(f"{API}/v2/projects/{pid}/generate", headers=h)
print(wait(pid)["translated_video"])// no dependencies, Node 18+ global fetch
const API = 'https://api.rask.ai';
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 call = (method, path, body) => fetch(API + path, { method, headers: h, body: body && JSON.stringify(body) }).then((r) => r.json());
const wait = async (id) => { let p; while ((p = await call('GET', `/v2/projects/${id}`)).status !== 'merging_done') await sleep(10000); return p; };
let video = await call('POST', '/api/library/v1/media/link', { link: 'https://youtu.be/...' });
while (video.status !== 'ready') { await sleep(5000); video = await call('GET', `/api/library/v1/media/${video.id}`); }
const { id } = await call('POST', '/v2/projects', { video_id: video.id, dst_lang: 'es-mx' });
const project = await wait(id);
const voices = await call('GET', `/v2/projects/${id}/voices`);
const custom = voices.find((v) => v.label === 'Maria Lopez');
await call('PATCH', `/v2/projects/${id}`, { voice: { ...project.voice, SPEAKER_00: custom.id } });
await call('POST', `/v2/projects/${id}/generate`);
console.log((await wait(id)).translated_video);# 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. create the dub - Instant Voice Clones are assigned by default
ID=$(curl -s -X POST https://api.rask.ai/v2/projects -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d "{\"video_id\": \"$VIDEO_ID\", \"dst_lang\": \"es-mx\"}" | jq -r .id)
# 3. after merging_done: read the current voice map and the voice options
curl -s https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN" | jq .voice
curl -s https://api.rask.ai/v2/projects/$ID/voices -H "Authorization: Bearer $TOKEN" | jq '.[] | {id, label, gender}'
# 4. assign voices for every speaker, then re-dub
curl -s -X PATCH https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"voice": {"SPEAKER_00": "<custom_voice_id>", "SPEAKER_01": "<voice_id>"}}'
curl -s -X POST https://api.rask.ai/v2/projects/$ID/generate -H "Authorization: Bearer $TOKEN"<?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']];
$wait = function ($id) use ($http, $h, $json) {
do { sleep(10); $p = $json($http->get("/v2/projects/$id", ['headers' => $h])); }
while ($p['status'] !== 'merging_done');
return $p;
};
$id = $json($http->post('/v2/projects', ['headers' => $h,
'json' => ['video_id' => $videoId, 'dst_lang' => 'es-mx']]))['id'];
$project = $wait($id);
$voices = $json($http->get("/v2/projects/$id/voices", ['headers' => $h]));
$custom = current(array_filter($voices, fn($v) => $v['label'] === 'Maria Lopez'));
$map = array_merge($project['voice'], ['SPEAKER_00' => $custom['id']]);
$http->patch("/v2/projects/$id", ['headers' => $h, 'json' => ['voice' => $map]]);
$http->post("/v2/projects/$id/generate", ['headers' => $h]);
echo $wait($id)['translated_video']; 0s created
11s transcription_started
87s translation_started
99s voiceover_started
154s merging_started
165s merging_done

es-mx 및 es-es 지원합니다. 프로젝트는 glossary_version을 기록하므로, 나중에 수정해도 완료된 작업이 예기치 않게 변경되지 않습니다.네. Rask 목소리 복제 API는 동영상 더빙 과정의 일환으로 각 화자의 목소리를 복제합니다. 목표 언어로 프로젝트를 생성하면 지원되는 언어 내에서 모든 화자의 즉석 목소리 복제가 이루어집니다. 또한 Rask 앱에서 직접 만든 맞춤형 목소리 복제를 원하는 화자에게 지정할 수도 있습니다.
즉석 목소리 복제는 지원되는 목표 언어에 맞춰 원본 동영상의 화자 목소리를 사용합니다. 다시 사용할 수 있는 맞춤형 목소리 복제를 원하시는 경우, 화자의 동의를 받아 Rask 앱에서 생성한 뒤 API를 통해 지정해 주세요. 결과는 원본 오디오, 선택한 언어 및 목소리에 따라 달라질 수 있습니다.
즉석 목소리 복제는 별도의 짧은 오디오 샘플을 녹음할 필요 없이 더빙하는 동영상의 음성으로부터 자동으로 생성됩니다. 맞춤형 목소리 복제는 한 번 업로드한 오디오 샘플을 기반으로 학습되며, 목소리 라이브러리에 저장되어 voice_id를 통해 모든 프로젝트에서 재사용할 수 있습니다. 목소리 목록에서 즉석 목소리 복제에는 "목소리 복제" 라벨과 성별 "auto"가 표시됩니다.
맞춤형 목소리 복제 생성은 Rask 웹 플랫폼에서 가능합니다. 복제가 저장되면 프로젝트 목소리 조회 엔드포인트(get project voices)를 통해 voice_id를 가져온 후 API를 통해 화자에게 지정할 수 있습니다.
1~10분 분량의 오디오 또는 동영상을 업로드하세요. 파일은 최대 10개까지, 각각 10MB 이하(MP4, MOV, WEBM, MKV, MP3, M4A, WAV 형식)로 지원되며 YouTube 또는 Google Drive 링크를 붙여넣을 수도 있습니다. 가장 좋은 결과를 얻으려면 좋은 마이크를 사용하고 배경 소음이 없는 조용한 방에서 일정한 말투로 녹음된 단일 화자의 오디오를 사용해 주세요.
목소리 복제 기능은 57개의 기본 언어와 해당 지역별 변형 버전을 지원합니다. 지역별 변형 버전은 기본 복제 모델을 사용합니다. 예를 들어, 영국식 영어 텍스트에는 미국식 영어 음성 모델이 사용됩니다. 다른 대상 언어의 경우 AI 음성 프리셋을 선택하세요. 전체 목록은 API 언어 카탈로그에서 확인하실 수 있습니다.
이 API는 오디오 전용 팟캐스트 및 인터뷰를 포함하여 동영상과 오디오 녹음 모두를 더빙합니다. 직접 작성한 문구를 사용하려면 번역된 텍스트를 구간별로 수정하거나, 프로젝트를 생성하기 전에 자체 .srt 파일로 대본을 만드세요. 그러면 복제된 목소리가 해당 텍스트를 읽어줍니다. 입력은 항상 녹음 파일 형태여야 하므로, 텍스트 전용 보이스오버의 경우 텍스트 음성 변환 API가 더 적합합니다.
GET /v2/projects/{id}/voices로 목소리 옵션을 가져온 다음, 변경된 화자와 변경되지 않은 모든 화자가 포함된 목소리 맵과 함께 PATCH /v2/projects/{id}를 전송하세요. 다시 더빙하려면 /generate를 호출하면 됩니다. 재더빙 요금은 변경된 구간의 총 지속 시간을 기준으로 청구되며, 유료 실행당 최소 1분이 적용됩니다.
크리에이터 프로(Creator Pro) 플랜은 최대 3개의 맞춤 목소리를, 비즈니스(Business) 플랜은 최대 10개의 팀 공유 목소리를, 엔터프라이즈(Enterprise) 플랜은 맞춤 목소리 라이브러리를 제공합니다.
네. 맞춤형 목소리 복제는 화자의 동의하에 생성되며, 화자가 동의한 동영상만 더빙해야 합니다. Rask는 동의 기반 목소리 복제 및 AI 안전 제어 기능을 사용하며, 오디오가 일반 모델 학습에 절대 사용되지 않습니다.
클론은 음색과 음높이를 포함한 화자의 음성 특성을 재현하므로, 다른 언어로 말할 때도 마치 본인이 말하는 것처럼 들립니다. 감정 톤, 억양, 리듬은 원본 오디오와 번역된 대본을 따르므로, 명확하고 표현력이 풍부한 원본 음성이 가장 좋은 결과를 가져옵니다.
원본 동영상의 사용 권한이 있고 화자의 동의를 얻은 경우, 상업용 콘텐츠에 복제된 목소리가 포함된 더빙 동영상을 게시할 수 있습니다. 이용 중인 요금제에 적용되는 세부 사항은 Rask 이용 약관을 확인하시기 바랍니다.
음성 복제는 더빙의 일부이며 별도의 요금이 부과되지 않습니다. API 사용 요금은 Rask 앱과 동일한 분 단위 할당량에서 동영상 분당 청구되며, 분 단위는 다음 정수로 올림 처리됩니다. 요금제 한도를 초과하는 분에 대해서는 분당 3달러가 청구됩니다. 음성 변경 후 재더빙 시에는 변경된 부분만 요금이 청구됩니다. 신용카드 없이 무료 체험을 시작해 보세요.