# 1. exchange client credentials for a token (valid 1 hour)
curl -X POST https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials"
# 2. upload the video once - YouTube, Drive, S3, Vimeo or direct URL
curl -X POST https://api.rask.ai/api/library/v1/media/link \
-H "Authorization: Bearer $TOKEN" \
-d '{"link": "https://youtu.be/...", "name": "Q3 launch"}'
# 3. one project per target language - they run in parallel
for lang in es-mx de-de ja-jp pt-br; do
curl -X POST https://api.rask.ai/v2/projects \
-H "Authorization: Bearer $TOKEN" \
-d "{\"video_id\": \"$VIDEO_ID\", \"dst_lang\": \"$lang\"}"
done# Poll each project until merging_done, then collect the files.
while :; do
curl -s https://api.rask.ai/v2/projects/$ID \
-H "Authorization: Bearer $TOKEN" \
| jq '{status, translated_video, translation_srt_path}'
sleep 10
done以多部分表单数据形式发送文件,或发布来自YouTube、Google Drive、S3、Vimeo或任何直接下载网址的链接。在您消费任何费用之前,即可获取媒体ID和技术元数据。
将媒体ID作为 video_id 传入并指定目标语言。利用同一次上传,为您所需的每种语言创建一个项目,同时可附带您自己的文稿或词汇表(如果有的话)。
读取状态直到显示merging_done,然后下载翻译后的视频和该语言的字幕文件。
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas
TARGETS = ["es-mx", "de-de", "ja-jp", "pt-br"]
async def translate(client, video_id, lang):
job = await client.create_project(
data=schemas.ProjectCreate(video_id=video_id, dst_lang=lang))
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)
jobs = await asyncio.gather(*(translate(client, video.id, l) for l in TARGETS))
for j in jobs:
print(j.dst_lang, j.translated_video, j.translation_srt_path)
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}"}
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()
ids = [requests.post(f"{API}/v2/projects", headers=h,
json={"video_id": video["id"], "dst_lang": lang}).json()["id"]
for lang in ["es-mx", "de-de", "ja-jp", "pt-br"]]
for pid in ids:
while (p := requests.get(f"{API}/v2/projects/{pid}", headers=h).json())["status"] != "merging_done":
time.sleep(10)
print(p["dst_lang"], p["translated_video"], p["translation_vtt_path"])// 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 get = (path) => fetch(API + path, { headers: h }).then((r) => r.json());
const post = (path, body) => fetch(API + path, { method: 'POST', headers: h, body: JSON.stringify(body) }).then((r) => r.json());
let video = await post('/api/library/v1/media/link', { link: 'https://youtu.be/...' });
while (video.status !== 'ready') { await sleep(5000); video = await get(`/api/library/v1/media/${video.id}`); }
const results = await Promise.all(['es-mx', 'de-de', 'ja-jp', 'pt-br'].map(async (dst_lang) => {
let p = await post('/v2/projects', { video_id: video.id, dst_lang });
while (p.status !== 'merging_done') { await sleep(10000); p = await get(`/v2/projects/${p.id}`); }
return p;
}));
results.forEach((p) => console.log(p.dst_lang, p.translated_video, p.translation_srt_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']];
$video = $json($http->post('/api/library/v1/media/link',
['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']]));
while ($video['status'] !== 'ready') {
sleep(5);
$video = $json($http->get("/api/library/v1/media/{$video['id']}", ['headers' => $h]));
}
foreach (['es-mx', 'de-de', 'ja-jp', 'pt-br'] as $lang) {
$p = $json($http->post('/v2/projects', ['headers' => $h,
'json' => ['video_id' => $video['id'], 'dst_lang' => $lang]]));
while ($p['status'] !== 'merging_done') {
sleep(10);
$p = $json($http->get("/v2/projects/{$p['id']}", ['headers' => $h]));
}
echo $lang, ' ', $p['translation_srt_path'], PHP_EOL;
}<?php
use GuzzleHttp\Client;
$http = new Client(['base_uri' => 'https://api.rask.ai']);
$auth = json_decode((new Client)->post(
'https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
['auth' => [$clientId, $clientSecret],
'form_params' => ['grant_type' => 'client_credentials']]
)->getBody(), true);
$h = ['Authorization' => 'Bearer ' . $auth['access_token']];
$media = json_decode($http->post('/api/library/v1/media/link',
['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']])->getBody(), true);
$project = json_decode($http->post('/v2/projects',
['headers' => $h, 'json' => ['video_id' => $media['id'], 'dst_lang' => 'es-mx']])->getBody(), true);
while ($project['status'] !== 'merging_done') {
sleep(10);
$project = json_decode($http->get("/v2/projects/{$project['id']}",
['headers' => $h])->getBody(), true);
}_done 状态。 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 只需要你提供视频文件或链接以及目标语言,就能自动完成语音转文字、翻译、配音生成并将声音与原背景音混合。你可以直接获取翻译好的视频、字幕文件和翻译文本,全程无需人工干预。如果追求极高的准确性,还可以在发布前添加人工审核环节。
付费套餐已包含 API 访问权限。你可以在应用中生成客户端 ID 和密钥,并立即开始调用。如需企业级条款、大容量定价和定制语言覆盖,请联系我们的团队。
使用 OAuth 2.0 客户端凭证。用你的客户端 ID 和密钥换取访问令牌,然后在每次请求时将其作为 bearer 令牌发送。令牌的有效期为一个小时,请将其缓存并重复使用。
采用异步处理。创建项目后会立即返回并开始翻译。你可以轮询 GET /v2/projects/{id},直到状态变为 merging_done。企业版用户支持 Webhook 消息推送。
没有限制。API 不会限制请求,也没有针对每个密钥的配额。你的处理吞吐量取决于处理队列的深度,而处理优先级是企业条款的一部分。
支持 135 种以上的目标语言,并在需要时提供地区变体,因此 dst_lang 参数支持诸如 es-mx 或 pt-br 的区域设置。系统会,你也可以手动设置。API 文档中列出了支持的完整语言列表。如果遇到目录中没有的语言,请联系我们的团队,探讨实现的可行性与可用方案。
是的。每个项目对应一种目标语言,因此您可以通过同一个上传文件为不同语言创建各自的项目并同时运行。没有速率限制,批量翻译成多种语言的速度完全取决于您的系统创建了多少个项目。
处理时间因项目而异。每个项目在经历转录、翻译、语音生成和合并时都会报告其状态,因此您可以向用户展示进度,并在翻译完成后下载文件。
支持七种视频格式(MP4、MOV、MKV、AVI、WebM、M4V、3GP)和四种音频格式(MP3、WAV、FLAC、M4A)。您还可以通过 YouTube、Google Drive、S3、Vimeo 或直接链接上传视频。
是的。除了翻译好的视频外,您还可以下载与翻译后的语音时间同步的 .srt 和 .vtt 格式的翻译字幕。嵌入视频中的字幕是在 Rask 应用中创建的。
是的。您可以获取文字稿,编辑源文本并让 Rask 重新翻译,或者直接编辑翻译后的文本以保留您自己的措辞和语调。然后重新配音。词汇表可确保品牌名称在所有语言版本中保持一致。
通用聊天模型可以翻译您粘贴给它的文字稿。要发布翻译好的视频,您还需要转录、时间轴、声音、音频混音和字幕文件。Rask 视频翻译 API 直接从视频文件中生成这些输出结果。
API 使用费按视频分钟数计费(向上取整至整分钟),并与 Rask 应用共享分钟数额度。超出套餐的分钟数收费为每分钟 3 美元,大宗采购条款可与我们的团队协商。唇形同步单独计费,每个账户都有一分钟的免费预览配额,修改后的重新配音仅对更改的部分计费。您可以先进行免费试用,无需绑定银行卡。