AI Subtitle Translation
Translate an existing subtitle file into another language, optionally applying the platform's built-in subtitle styles and colors, or producing bilingual subtitles.
This capability does not perform speech recognition and does not accept audio or video input. To generate subtitles from a video or audio file, use AI Subtitle Recognition.
| AI Subtitle Recognition | AI Subtitle Translation (this page) | |
|---|---|---|
| Input | Audio or video file | Subtitle file .ass / .srt |
| What it does | Speech recognition to generate subtitles (can also translate) | Translates existing subtitles |
| Billing | Per video minute | Per character (per 1,000 characters) |
Use this capability when you already have proofread subtitles and want another language: it does not re-run speech recognition, and it does not overwrite your existing proofreading.
⚠️ Behavior change (2026-08-22): As of 2026-08-22, this API strips Chinese and English commas and periods from the translated subtitle text by default (
strip_punctuationdefaults totrue, see the parameter table below), so identical requests produce different subtitle text than before the upgrade; timecodes, line counts, and all other output fields are unchanged. To keep the previous behavior, passstrip_punctuation: falseexplicitly.
Create Task
Basic Information
| Item | Value |
|---|---|
| Request Method | POST |
| Request Path | /task/subtitle_translate |
| Content-Type | application/json |
| Authentication | Raw API key in the Authorization header |
Request Body
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
file_id | string | Yes | - | Uploaded subtitle file ID. Only .ass / .srt are accepted; audio or video files are rejected |
language | string | Yes | - | Subtitle source language code. See the full supported list below |
translate_language | string | Yes | - | Target language code for translation. It uses the same supported set as language |
output_format | string | No | Follows input | Output format: ass or srt. When omitted, .ass in produces .ass out and .srt in produces .srt out |
line_mode | string | No | "resegment" | Translation granularity. See "Translation Granularity" below |
lingual_type | string | No | "monolingual" | monolingual or bilingual (source and translation shown together). Only effective for ass output |
subtitle_type | string | No | "default" | Subtitle style preset: default, outline, cinema_yellow, immersive_box, wide_spacing, deep_shadow, or boxed. Only effective for ass output |
subtitle_color | string | No | "雅黑" | Subtitle color preset: 雅黑, 淡绿, 森林绿, 湖蓝, 道奇蓝, 钢蓝, 浅粉红, 深橙, 珊瑚橙, 橙红, or 土豪金. Only effective for ass output |
video_size | array | No | [1920, 1080] | Canvas geometry [width, height], which determines how translated lines are wrapped. See "Canvas Geometry" below |
strip_punctuation | boolean | No | true | Punctuation stripping for the translated subtitle text: stripping is on by default (punctuation looks poor in subtitles) — Chinese , 。 and English , . are replaced with spaces, in-word forms are exempt (decimals 3.5, domains example.com, thousands separators 1,000 stay intact), and all other punctuation (quotes, question marks, exclamation marks, dashes, etc.) is kept; consecutive spaces collapse to one and line edges are trimmed. Only the subtitle text is affected — timecodes, line counts, and all other output fields are unchanged. Pass false explicitly to keep punctuation intact |
Supported Language Codes
language and translate_language use the same language set as AI Subtitle Recognition, supporting these 11 languages:
| Language code | Language name |
|---|---|
zh-CHT | Traditional Chinese |
zh-CHS | Simplified Chinese |
zh-CN | Chinese |
ja-JP | Japanese |
en-US | English |
es-ES | Spanish |
ru-RU | Russian |
ko-KR | Korean |
fr-FR | French |
pt-PT | Portuguese |
vi-VN | Vietnamese |
Translation Granularity (line_mode)
A single sentence is often split across several adjacent subtitle lines. How those breaks are handled determines both how natural the translation reads and whether the timeline stays intact — you cannot have both, so choose by need.
| Value | How it works | What you get | Trade-off |
|---|---|---|---|
resegment (default) | Merges adjacent lines back into full sentences before translating, then re-wraps for the target language | More natural translation, with line breaks that suit the target language | Line count and timeline change; they no longer map one-to-one to the input |
keep | Translates strictly line by line, never merging across lines | Timeline matches the input line for line, so the track can directly replace the original | Line-by-line translation lacks context, and short gaps between the original lines are preserved |
Use
keepwhen the translated track must drop straight back into an existing edit and the timecodes have to line up. Use the defaultresegmentwhen you simply want a translation that reads well.
Canvas Geometry (video_size)
A translation is rarely the same length as the source, so lines must be re-wrapped to the picture width — which requires knowing the canvas size. Resolution order:
- This
video_sizeparameter PlayResin the.assfile header- Server default
1920x1080(landscape)
.srtfiles carry no canvas information, so nothing can be inferred from the file. For portrait output, always passvideo_sizeexplicitly; otherwise lines are wrapped for landscape and may run past the edge of the picture.
How Styles Relate to Output Format
subtitle_type, subtitle_color, and lingual_type all rely on the ASS format to carry style information. The SRT format carries no styling.
Therefore, if output_format is srt and any of those three parameters is also supplied, the request is rejected at task creation and no credits are charged.
The check is based on the output format, not the input format. Using a
.srtinput while requestingassoutput with styles is entirely valid — that is the normal way to upgrade plain-text subtitles into styled ones.
Size Limits
Each task has subtitle size limits. Exceeding any of them rejects the request at task creation with no charge:
| Dimension | Limit |
|---|---|
| Subtitle entries | 2000 |
| Total characters | 80000 |
| File size | 8 MB |
Split the file and submit in batches when you exceed a limit. For reference, a 90-minute feature film typically has 1,200–1,800 subtitle entries.
Request Example
curl -X POST https://api.ai-mcn.tv:10000/task/subtitle_translate \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_id": "537489015178246",
"language": "zh-CN",
"translate_language": "en-US",
"output_format": "ass",
"line_mode": "resegment",
"lingual_type": "bilingual",
"subtitle_type": "boxed",
"subtitle_color": "珊瑚橙",
"video_size": [1920, 1080]
}'
Success Response Example
{
"code": 200,
"msg": "success",
"data": {
"task_id": "537489015178247",
"task_type": "subtitle_translate",
"status": "queued"
}
}
Query Task Result
Basic Information
| Item | Value |
|---|---|
| Request Method | GET |
| Request Path | /task/subtitle_translate/{task_id} |
| Authentication | Raw API key in the Authorization header |
Response Fields (output_result)
| Parameter | Type | Description |
|---|---|---|
subtitle_file_id | string | Translated subtitle file ID |
subtitle_file_download_url | string | Translated subtitle download link |
output_format | string | Actual output format (ass or srt) |
line_mode | string | Translation granularity actually used |
stats | object | Entry counts, see below |
degraded | object | Degradation flags, see below |
stats object
| Parameter | Type | Description |
|---|---|---|
input_lines | integer | Number of input subtitle entries |
output_lines | integer | Number of output entries (differing from the input is expected under resegment) |
skipped_total | integer | Total entries skipped across all stages |
skipped_totalcovers zero-duration entries and malformed blocks dropped while reading, zero-duration entries newly produced by re-wrapping, and empty text segments dropped while writing. A non-zero value is worth a quick check of the output.
degraded object
Three booleans. Any true means the output has a perceptible but non-failing quality difference, which you can use to decide whether to re-run:
| Parameter | Meaning |
|---|---|
summary | Context summary could not be produced; terminology consistency across the file may be lower |
width_budget | Render width budget could not be computed; lines were wrapped by semantic length only, so some may run past the edge of the picture |
translation | The translation pipeline fell back to chunked retry or machine translation; translation quality may be lower |
Success Response Example
{
"code": 200,
"msg": "success",
"data": {
"task_id": "537489015178247",
"status": "completed",
"progress": 100,
"output_result": {
"subtitle_file_id": "537489015178249",
"subtitle_file_download_url": "https://api.ai-mcn.tv:9000/cloud/file/ef/537489015178249.ass",
"output_format": "ass",
"line_mode": "resegment",
"stats": {
"input_lines": 420,
"output_lines": 386,
"skipped_total": 2
},
"degraded": {
"summary": false,
"width_budget": false,
"translation": false
}
},
"create_time": "2026-04-05T08:00:00Z",
"update_time": "2026-04-05T08:01:30Z"
}
}
Billing
Billed per character, at 1 credit per 1,000 characters.
- Billable units = total subtitle characters ÷ 1000 (fractional units are preserved)
- Characters are counted as Unicode code points; one Chinese, Japanese, or Korean character counts as 1 character
- The final charge is rounded up to a whole credit; any non-empty subtitle costs at least 1 credit
| Total characters | Charge |
|---|---|
| 1,000 | 1 credit |
| 1,500 | 2 credits |
| 50,000 | 50 credits |
| 80,000 (limit) | 80 credits |
Only subtitle text counts toward billing; timecodes and entry numbers do not. Every request rejected at task creation (invalid parameters, format conflict, size limit exceeded, or an unusable subtitle file) is free of charge.
Error Codes
| Error code | HTTP status | Description | Resolution |
|---|---|---|---|
6013 | 400 | Missing file_id, language, or translate_language | Supply the required parameters |
6014 | 400 | File type mismatch | This capability accepts only .ass / .srt; for audio or video use AI Subtitle Recognition |
6016 | 400 | Invalid parameter value, srt output conflicting with style parameters, size limit exceeded, or an unusable subtitle file (empty, malformed, or multi-layer bilingual) | Adjust per the error message; none of these are charged |
5202 | 404 | File does not exist | Verify the file_id |
6502 | 401 | Authentication failed | Check the Authorization header |
6201 | 402 | Insufficient balance | Top up from the dashboard |
Submitting a bilingual subtitle file (two entries covering the same time range) is rejected: there is no reliable way to tell which layer is the source, and guessing wrong would translate an already-translated line a second time. Split out the layer you want translated first.