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