# 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ドライブ、S3、Vimeoなどのリンク、または直接ダウンロード用のURLを投稿します。費用が発生する前に、メディアIDと技術的なメタデータを受け取ることができます。
メディアIDを video_id として渡し、ターゲット言語を指定します。1回のアップロードから、独自の文字起こしや用語集を使用して、必要な言語ごとにプロジェクトをそれぞれ作成できます。
status が 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 states。 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とシークレットをアクセストークンに交換し、すべてのリクエストでベアラートークンとして送信します。トークンの有効期限は1時間ですので、キャッシュして再利用してください。
非同期処理となります。プロジェクトの作成後すぐにレスポンスが返り、翻訳が開始されます。ステータスが「merging_done」になるまで「GET /v2/projects/{id}」でポーリングを行ってください。Webhookの配信は、エンタープライズ向けのご案内に含まれています。
制限はありません。APIはリクエストの速度制限を行わず、キーごとの割当量もありません。処理能力は処理キューの深さによって制限され、処理の優先度は企業向け契約条件の一部となります。
135以上のターゲット言語に対応しており、必要に応じてes-mxやpt-brなどの地域バリエーションも指定できます(dst_langで指定)。元言語は自動検出されますが、手動で設定することも可能です。サポートされている言語の全リストはAPIドキュメントに記載されています。対応言語リストにない言語については、実現可能性や利用可能なオプションについて弊社チームまでお問い合わせください。
はい。1つのプロジェクトにつき1つの言語を指定するため、同じ動画をアップロードして言語ごとにプロジェクトを作成し、同時に処理を進めることができます。利用制限がないため、複数の言語への一括翻訳は、システムで作成するプロジェクト数のみに依存します。
処理時間はプロジェクトによって異なります。文字起こし、翻訳、音声の生成、そして動画と音声の結合といった各工程の進捗状況がプロジェクトごとに表示されるため、ユーザーに進捗を伝えたり、翻訳完了後にファイルをダウンロードしたりすることが可能です。
7つの動画形式(MP4、MOV、MKV、AVI、WebM、M4V、3GP)と4つの音声形式(MP3、WAV、FLAC、M4A)に対応しています。また、YouTube、Google Drive、S3、Vimeo、または直接のURLから動画をアップロードすることもできます。
はい。翻訳された音声のタイミングに合わせた.srtおよび.vtt形式の字幕を、翻訳済み動画と一緒にダウンロードできます。動画に焼き付けられた字幕は、Raskアプリ内で作成されます。
はい。文字起こしデータを取得して元のテキストを編集し、Raskで再度翻訳させたり、翻訳されたテキストを直接編集してご自身の表現やトーンを維持したりすることができます。その後、プロジェクトの音声を再生成してください。用語集を使用することで、すべての言語バージョンでブランド名を一貫させることができます。
一般的なチャットモデルであれば、貼り付けられた文字起こしを翻訳することは可能です。ただし、翻訳された動画を公開するには、文字起こし、タイミングの調整、音声生成、ミキシング、字幕ファイルの作成も必要になります。Raskの動画翻訳APIは、動画ファイルから直接これらの出力を生成します。
APIの利用料金は動画の分数に応じて課金され(1分未満の端数は切り上げ)、Raskアプリの持ち分時間から消化されます。プランに含まれる分数を超過した場合は1分あたり3ドルとなり、大量利用については別途ご相談となります。リップシンク(口パク合わせ)は別料金となりますが、どのアカウントでも1分間の無料プレビューをご利用いただけます。また、編集後の音声再生成は、変更された部分に対してのみ課金されます。まずはクレジットカード不要の無料トライアルからお試しください。