# 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 或任何直链的链接。视频中的语音即为每个即时语音克隆的参考样本。
将媒体 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 重复使用。在语音列表中,即时声音克隆带有“声音克隆”标签,性别为“自动”。
创建定制声音克隆功能可在 Rask 网页平台上使用。保存克隆后,通过获取项目语音端点检索其 voice_id,然后通过 API 将其分配给说话者。
请上传1到10分钟的音频或视频,文件数量最多10个,每个文件最大10 MB,支持MP4、MOV、WEBM、MKV、MP3、M4A或WAV格式,也可以粘贴YouTube或Google Drive链接。为了获得最佳效果,请使用单一说话人、说话风格保持一致的录音,并在安静的房间内使用优质麦克风录制,无背景噪音。
声音克隆支持32种基础语言及其支持的地区变体。地区变体使用基础克隆模型:例如,英式英语文本使用美式英语声音模型。对于其他目标语言,请选择AI声音预设。完整列表请参见API语言目录。
该API可对视频和音频录音进行配音,包括纯音频播客和采访。若要使用您自己的措辞,请逐段编辑翻译后的文本,或者在创建项目前使用您自己的.srt文件创建转写,克隆的声音便会朗读您的文本。输入始终是录音,因此对于纯文本配音,文字转语音API会更合适。
通过 GET /v2/projects/{id}/voices 获取声音选项,然后发送包含所有说话人(包括已更改和未更改的说话人)声音映射的 PATCH /v2/projects/{id}。调用 /generate 重新配音。重新配音根据已更改片段的总时长计费,每次收费运行最低一分钟。
创作者专业版方案包含最多3个自定义声音,商业版方案包含最多10个共享团队声音,企业版方案则提供自定义声音库。
是的。自定义声音克隆是在征得说话人同意的情况下创建的,您只能为说话人已同意的视频配音。Rask采用基于同意的声音克隆和AI安全控制,您的音频绝不会用于训练通用模型。
克隆会复制说话人的声音特征,包括音色和音高,让他们在另一种语言中听起来依然像他们自己。情感基调、语速和节奏则遵循源音频和翻译后的脚本,因此清晰、富有表现力的源语音能带来最佳效果。
我可以将克隆的声音用于商业用途吗?
声音克隆是配音的一部分,不收取单独费用:API使用费按视频分钟数计费,向上取整至下一整分钟,从Rask应用的同一分钟额度中扣除。超出方案的分钟数按每分钟3美元收费。更改声音后的重新配音仅对更改的片段计费。立即开始免费试用,无需信用卡。