# 1. 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" -H "Content-Type: application/json" \
-d '{"link": "https://example.com/onboarding.mp4", "name": "onboarding"}'
# 2. one project per subtitle language
for lang in es-mx fr-fr ja-jp; 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\"}"
done# When status is merging_done, download both subtitle files
P=$(curl -s https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN")
curl -s -o onboarding.es-mx.srt "$(echo $P | jq -r .translation_srt_path)"
curl -s -o onboarding.es-mx.vtt "$(echo $P | jq -r .translation_vtt_path)"동영상 파일을 업로드하거나 YouTube, Google Drive, S3, Vimeo 또는 기타 직접 링크를 입력하세요. 한 번만 업로드하면 모든 언어의 자막을 만들 수 있습니다.
미디어 ID를 video_id로 전달하고 프로젝트당 하나의 타겟 언어를 지정하세요. 언어별 프로젝트는 동시에 실행됩니다.
상태가 merging_done에 도달할 때까지 확인한 후, .srt 및 .vtt 파일을 다운로드하여 저장하세요.
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio, urllib.request
from rask_sdk import clients, enums, schemas
LANGS = ["es-mx", "fr-fr", "ja-jp"]
async def subtitle(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)
# links are presigned for one hour - save the files right away
urllib.request.urlretrieve(job.translation_srt_path, f"video.{lang}.srt")
urllib.request.urlretrieve(job.translation_vtt_path, f"video.{lang}.vtt")
async def main():
client = clients.RaskSDKClient(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
media = await client.create_media_link(data=schemas.MediaCreateLink(link="https://example.com/onboarding.mp4"))
while media.status is enums.MediaStatus.PROCESSING:
await asyncio.sleep(5)
media = await client.get_media(media_id=media.id)
await asyncio.gather(*(subtitle(client, media.id, l) for l in LANGS))
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}"}
pid = requests.post(f"{API}/v2/projects", headers=h,
json={"video_id": VIDEO_ID, "dst_lang": "de-de"}).json()["id"]
while (p := requests.get(f"{API}/v2/projects/{pid}", headers=h).json())["status"] != "merging_done":
time.sleep(10)
# translated subtitles: download the files
open("video.de-de.vtt", "wb").write(requests.get(p["translation_vtt_path"]).content)
# original-language captions: build a WebVTT file from the transcript segments
segs = requests.get(f"{API}/v2/projects/{pid}/transcription", headers=h).json()["segments"]
cues = [f"{s['start'].replace(',', '.')} --> {s['end'].replace(',', '.')}\n{s['src']['text']}" for s in segs]
open("video.en.vtt", "w").write("WEBVTT\n\n" + "\n\n".join(cues) + "\n")// no dependencies, Node 18+ global fetch
import { writeFile } from 'node:fs/promises';
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 langs = ['es-mx', 'pt-br', 'ko-kr'];
const tracks = await Promise.all(langs.map(async (dst_lang) => {
let p = await call('POST', '/v2/projects', { video_id: VIDEO_ID, dst_lang });
while (p.status !== 'merging_done') { await sleep(10000); p = await call('GET', `/v2/projects/${p.id}`); }
const file = `subs/${dst_lang}.vtt`;
await writeFile(file, await ((await fetch(p.translation_vtt_path)).text()));
return `<track kind="subtitles" srclang="${dst_lang}" src="/${file}">`;
}));
console.log(tracks.join('\n')); // paste inside your <video> element# 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 project for one subtitle language
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\": \"it-it\"}" | jq -r .id)
# 3. wait for merging_done
until [ "$(curl -s https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN" | jq -r .status)" = merging_done ]; do
sleep 10
done
# 4. save both subtitle files
P=$(curl -s https://api.rask.ai/v2/projects/$ID -H "Authorization: Bearer $TOKEN")
curl -s -o video.it-it.srt "$(echo $P | jq -r .translation_srt_path)"
curl -s -o video.it-it.vtt "$(echo $P | jq -r .translation_vtt_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']];
foreach (['es-mx', 'tr-tr'] as $lang) {
$p = $json($http->post('/v2/projects', ['headers' => $h, 'json' => [
'video_id' => $videoId, 'dst_lang' => $lang]]));
while ($p['status'] !== 'merging_done') {
sleep(10);
$p = $json($http->get("/v2/projects/{$p['id']}", ['headers' => $h]));
}
// presigned links, valid for one hour
file_put_contents("video.$lang.srt", file_get_contents($p['translation_srt_path']));
file_put_contents("video.$lang.vtt", file_get_contents($p['translation_vtt_path']));
} 0s created
11s transcription_started
87s translation_started
99s voiceover_started
154s merging_started
165s merging_done

es-mx 및 es-es 지원합니다. 프로젝트는 glossary_version을 기록하므로, 나중에 수정해도 완료된 작업이 예기치 않게 변경되지 않습니다.네. 모든 Rask 프로젝트는 목표 언어로 된 SRT 및 WebVTT 자막 파일을 제공합니다. 동영상을 업로드하고 자막 언어별로 프로젝트를 생성한 뒤, 완료되면 파일을 다운로드하세요.
프로젝트마다 목표 언어로 된 SRT 파일과 WebVTT(VTT) 파일의 두 가지 형식이 제공됩니다. 플랫폼에서 다른 자막 형식이 필요한 경우, 타임스탬프가 포함된 JSON 세그먼트로도 대본을 이용할 수 있습니다.
자막 파일은 목표 언어로 제공됩니다. 원래 언어의 자막이 필요한 경우 대본 세그먼트를 확인하세요. 각 세그먼트에는 시작 및 종료 시간이 포함된 원본 텍스트가 있어, 몇 줄의 코드로 SRT 또는 VTT 파일로 변환할 수 있습니다.
자막은 75개의 원본 언어에서 es-mx, pt-br, fr-ca와 같은 지역별 옵션을 포함해 135개 이상의 언어로 제공됩니다. 각 프로젝트는 하나의 목표 언어를 사용하므로, 동일한 업로드 파일에서 언어별로 프로젝트를 생성하세요.
아직 지원되지 않습니다. API는 플레이어나 동영상 편집 소프트웨어용 자막 파일을 제공합니다. 자막이 포함된 동영상을 얻으려면 Rask 웹 앱을 사용하세요.
파일에는 텍스트와 타이밍이 포함됩니다. 글꼴, 크기, 색상, 위치는 동영상 플레이어, 앱 또는 편집 소프트웨어에서 설정하므로 하나의 자막 파일로 어디서나 사용할 수 있습니다.
파일에는 말소리 대화가 포함됩니다. 청각 장애인을 위한 음악 및 음향 효과 설명은 자동으로 생성되지 않으므로, 자막 편집 단계에서 직접 추가해 주세요.
각 대본 세그먼트에는 SPEAKER_XX 형식의 화자 레이블이 포함되어 있어, 인터뷰나 대화 자막을 만들 때 화자 이름을 추가할 수 있습니다.
API를 통해 해당 세그먼트의 텍스트나 타이밍을 수정한 후 프로젝트를 다시 생성하세요. 자막 파일은 더빙 버전과 함께 업데이트됩니다. 재생성은 변경된 세그먼트를 기준으로 과금되며, 실행당 최소 1분이 부과됩니다.
다운로드 링크는 사전 서명되며 1시간 동안 유효합니다. 파일을 개인 저장소에 저장하거나 프로젝트를 다시 불러와 새로운 링크를 받으세요.
네. 자막 가져오기 기능이 포함된 요금제의 경우, 프로젝트를 만들 때 원본 언어 자막, 승인된 번역 언어 SRT 파일 또는 둘 다 업로드할 수 있습니다. 기존 자막을 원본으로 사용하거나, 번역 언어 자막 및 더빙용으로 승인된 번역본을 그대로 사용할 수 있습니다.
프로젝트 비용은 동영상 길이를 분 단위로 올림하여 Rask 앱과 동일한 제공량에서 차감됩니다. 가격에는 전사, 번역, 자막 및 더빙 버전이 모두 포함됩니다. 지원되는 일반 요금제에서는 추가 분당 3달러가 부과되며, 기업용 요금제(Enterprise)는 계약에 따라 맞춤형으로 책정됩니다.
API 이용은 Creator Pro, Business, Enterprise 요금제에서 가능하며, 요금제에 따라 제공되는 기능이 다릅니다. 앱에서 클라이언트 ID와 시크릿을 생성하고 즉시 연동을 시작할 수 있습니다. 기업용 조건, 대량 할인, 맞춤형 언어 지원은 당사 팀으로 문의해 주세요.