# 1. one Spanish glossary - it applies to every Spanish regional variant
curl -X POST https://api.rask.ai/v2/glossaries \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Brand terms", "src_lang": "en", "dst_lang": "es",
"entries": {"Rask Studio": "Rask Studio", "onboarding": "incorporación"}}'
# 2. a localized version per market, both with the same glossary
for lang in es-mx es-es; do
curl -X POST https://api.rask.ai/v2/projects \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"video_id\": \"$VIDEO_ID\", \"dst_lang\": \"$lang\", \"glossary_id\": \"$GLOSSARY_ID\"}"
done# Review: source and translated text, segment by segment
curl -s https://api.rask.ai/v2/projects/$ID/transcription \
-H "Authorization: Bearer $TOKEN" \
| jq '.segments[] | {speaker, src: .src.text, dst: .dst.text}'为每组语言对创建术语表,为经常出镜的主持人保存自定义配音,并为每个发布市场选择相应的地区语言环境。
将源视频上传一次,然后针对每个目标语言地区创建一个项目,并使用您的术语表,或导入从 SRT 文件中获取的已审核译文。
将译文与原文并排对照阅读,修改审校人员标注的内容,对修改后的片段重新配音,并下载本地化的视频和字幕。
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas
MARKETS = ["es-mx", "es-es"]
async def localize(client, video_id, locale, glossary_id):
job = await client.create_project(data=schemas.ProjectCreate(
video_id=video_id, dst_lang=locale, glossary_id=glossary_id))
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)
glossary = await client.create_glossary(data=schemas.GlossaryCreate(
name="Brand terms", src_lang="en", dst_lang="es",
entries={"Rask Studio": "Rask Studio", "onboarding": "incorporación"}))
jobs = await asyncio.gather(*(localize(client, VIDEO_ID, m, glossary.id) for m in MARKETS))
for job in jobs: # review before publishing
script = await client.get_project_transcription(project_id=job.id)
for seg in script.segments[:3]:
print(job.dst_lang, seg.speaker, seg.src.text, "->", seg.dst.text)
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}"}
glossary = requests.post(f"{API}/v2/glossaries", headers=h, json={
"name": "Brand terms", "src_lang": "en", "dst_lang": "es",
"entries": {"Rask Studio": "Rask Studio", "onboarding": "incorporación"}}).json()
ids = [requests.post(f"{API}/v2/projects", headers=h, json={
"video_id": VIDEO_ID, "dst_lang": locale, "glossary_id": glossary["id"]}).json()["id"]
for locale in ["es-mx", "es-es"]]
for pid in ids:
while requests.get(f"{API}/v2/projects/{pid}", headers=h).json()["status"] != "merging_done":
time.sleep(10)
script = requests.get(f"{API}/v2/projects/{pid}/transcription", headers=h).json()
for seg in script["segments"][:3]:
print(seg["src"]["text"], "->", seg["dst"]["text"])// 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 glossary = await call('POST', '/v2/glossaries', {
name: 'Brand terms', src_lang: 'en', dst_lang: 'es',
entries: { 'Rask Studio': 'Rask Studio', onboarding: 'incorporación' },
});
for (const dst_lang of ['es-mx', 'es-es']) {
let p = await call('POST', '/v2/projects', { video_id: VIDEO_ID, dst_lang, glossary_id: glossary.id });
while (p.status !== 'merging_done') { await sleep(10000); p = await call('GET', `/v2/projects/${p.id}`); }
const { segments } = await call('GET', `/v2/projects/${p.id}/transcription`);
segments.slice(0, 3).forEach((s) => console.log(dst_lang, s.src.text, '->', s.dst.text));
}# 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. import the translation your reviewers approved (source and translated .srt)
TRANSCRIPT_ID=$(curl -s -X POST "https://api.rask.ai/v2/transcriptions/srt?src_lang=en&dst_lang=es-mx" \
-H "Authorization: Bearer $TOKEN" \
-F "src=@source_en.srt" -F "dst=@approved_es-mx.srt" | jq -r .id)
# 3. create the localized version from it - Rask voices the approved script
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\", \"transcript_id\": \"$TRANSCRIPT_ID\"}"<?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']];
$glossary = $json($http->post('/v2/glossaries', ['headers' => $h, 'json' => [
'name' => 'Brand terms', 'src_lang' => 'en', 'dst_lang' => 'es',
'entries' => ['Rask Studio' => 'Rask Studio', 'onboarding' => 'incorporación'],
]]));
foreach (['es-mx', 'es-es'] as $locale) {
$p = $json($http->post('/v2/projects', ['headers' => $h, 'json' => [
'video_id' => $videoId, 'dst_lang' => $locale, 'glossary_id' => $glossary['id']]]));
while ($p['status'] !== 'merging_done') {
sleep(10);
$p = $json($http->get("/v2/projects/{$p['id']}", ['headers' => $h]));
}
$script = $json($http->get("/v2/projects/{$p['id']}/transcription", ['headers' => $h]));
echo $locale, ': ', $script['segments'][0]['dst']['text'], PHP_EOL;
} 0s created
11s transcription_started
87s translation_started
99s voiceover_started
154s merging_started
165s merging_done

es-mx 和 es-es 类似内容。项目记录 glossary_version,因此后续的修改绝不会悄悄改变已完成的工作。视频本地化 API 可通过您自己的代码实现自动化处理,将一段源视频转换为面向不同市场的多种版本:包括翻译和配音、字幕、统一的术语以及可选的唇形同步。借助 Rask,每个市场版本都是您通过一个 REST API 创建、审核并下载的项目。
翻译只是改变文字内容。本地化则是针对特定市场对同一视频进行适配:包括区域语言版本、保持一致的品牌术语、配音、字幕,以及发布前的审核环节。Rask API 通过一个工作流即可支持所有这些环节。
是的。请为每个目标地区分别创建一个项目,例如墨西哥的 es-mx 和西班牙的 es-es,并复用同一份西班牙语术语表以确保品牌术语的一致性。请针对每个市场审核相关措辞。当地区口音至关重要时,请选择该地区可用的 AI 语音预设;语音克隆功能基于基础语言模型,无法保证呈现出鲜明的地区口音。
请为每对语言创建一个术语表,并在创建项目时将其附加到项目中。每个项目都会记录其使用的术语表版本,因此后续编辑术语表绝不会影响已完成的工作。项目创建后,无法再向其中添加术语表。
是的,支持带有SRT上传功能的套餐。在创建项目时,请导入已审核的目标语言SRT文件;源语言SRT文件可选。如果您同时拥有这两个文件,也可以一并提供。Rask会使用您已审核的译文进行配音。
文化相关性需要人工判断。该API为审稿人提供了每个片段,以便他们在发布前根据目标市场调整其中的参考内容、习语和示例;当您的团队无法审核每段视频时,Rask还可以在工作流中加入人工质量保证环节。
文档中记录的 API 端点可对语音和字幕进行本地化处理。图片中的文字(例如视频片段中的标题)将保持拍摄时的原样。如果屏幕上的文字是您本地化工作流程的一部分,请与我们的团队联系。
可从 135 多种语言和地区选项中选择,进行多语言本地化,包括墨西哥西班牙语、欧洲西班牙语、巴西葡萄牙语、欧洲葡萄牙语和加拿大法语。每个项目仅支持一种目标语言环境。完整列表请参见 API 文档,若需其他选项,我们的团队可与您商讨。
是的,在支持语音克隆的语言中可以实现。您可以使用“即时语音克隆”功能来保留说话者的独特风格,或者针对经常出场的主持人使用已保存的“自定义语音克隆”。语音克隆功能基于基础语言模型,因此选择特定地区的语言环境并不能保证会呈现该地区的口音。若优先考虑地区口音,请选择可用的AI语音预设。
对于真人出镜说话的视频片段,口型同步是一项可选步骤。请在审核完成后,对本地化版本进行口型同步处理。每次对完整视频进行口型同步生成的费用均与配音费用分开计费,包括后续编辑后的生成操作。
API的使用费用按每个市场版本的视频分钟数计费,计费所用的分钟数池与Rask应用相同。符合条件的标准套餐中,额外分钟数按每分钟3美元收费。 企业版定价将根据您的协议量身定制。审核后的重新配音将按修改片段的总时长计费,每次处理的最低计费单位为1分钟,口型同步服务将单独计费。您可以在Rask应用中通过免费试用体验本地化服务,无需绑定信用卡。如需评估API,请预约我们的团队进行演示。
是的。对于定期翻译任务,我们的团队可以协助您梳理现有流程、界定审阅和审批阶段、配置术语和语体风格、将 Rask 与您的内容管理系统(CMS)或学习管理系统(LMS)对接,并在必要时安排人工质量检查。
创建者专业版(Creator Pro)、商业版和企业版套餐均提供API访问权限,具体功能取决于您的套餐。您可以在应用中生成客户端ID和密钥并立即开始调用。企业版条款、批量定价和定制语言范围需通过我们的团队沟通。