---
url: /docs/asr_text_align.zh.md
description: 文本对齐时间线接口。用音频识别结果为你给定的文本生成行级时间线，同时返回音频的字级时间线（微秒）。
---

# ASR\_TEXT\_ALIGN API 接口文档

## 🌐 语言切换

[中文版](/docs/asr_text_align.zh) | [English](/docs/asr_text_align)

## 接口信息

```
POST /openapi/autosubrt/v1/asr/text/align
```

::: warning 这是语音识别服务
本接口的基地址是 `https://autosubrt.jcaigc.cn`，与剪映小助手（`https://capcut-mate.jcaigc.cn`）不是同一个服务，路径前缀也不同。

```
完整请求地址 = https://autosubrt.jcaigc.cn + /openapi/autosubrt/v1/asr/text/align
```

:::

## 功能描述

把**你提供的文本**按音频的时间轴对齐：服务端先识别音频，再把文本切成一行行字幕，给出每行的起止时间，同时返回音频里每个字的时间线。

适合「文案已经写好，只需要卡时间」的场景（如已有人工校对过的台词稿）。识别结果本身就是你要的文案时，用 [语音转文案](/docs/asr.zh) 更省事。

::: warning 时间单位是微秒
本接口返回的时间线单位是**微秒**（1 秒 = 1000000），而 [语音转文案](/docs/asr.zh) 返回的是**毫秒**，两者相差 1000 倍。
:::

## 请求参数

```json
{
  "audio_url": "https://example.com/audio.mp3",
  "text": "多谢，请入席吧。",
  "max_chars_per_line": 15,
  "apiKey": "123e4567-e89b-12d3-a456-426614174000"
}
```

### 参数说明

| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| audio\_url | string | ✅ | - | 音频文件 URL，需可被服务端直接下载 |
| text | string | ✅ | - | 与该音频对应的字幕文本 |
| max\_chars\_per\_line | int | ❌ | 15 | 每行最大字数，超过则拆成多条字幕 |
| apiKey | string | 开启计费时必填 | - | 合法 UUID；可登录 https://jcaigc.cn 获取 |

### 参数详解

#### audio\_url

* **类型**: string
* **说明**: 服务端会先把这个 URL 下载到本地再识别，因此必须是**可直接访问的直链**（不能是需要登录的网页地址）
* **格式**: 常见音视频文件均可，如 wav、mp3、m4a、aac、flac、ogg，mp4、mov 等视频文件也能直接传（服务端自动抽取音轨）
* **限制**: 单文件最大 100MB（服务端 `FILE_SIZE_LIMIT` 默认 104857600 字节）

#### text

* **类型**: string
* **说明**: 需要对齐的字幕文本，行内容应与音频实际说的一致
* **切分规则**: 先按标点切句（`。！？，；.!?,;:` 与换行都会切开），**切分后标点被去掉**；超过 `max_chars_per_line` 的句子会再平均拆成多行

#### max\_chars\_per\_line

* **类型**: int
* **说明**: 每行最大字数，默认 15。拆分是「平均分」而不是「按标点分」：30 字分成 2 行各 15 字；31 字分成 3 行（11、10、10）；46 字分成 4 行（12、12、11、11）

#### apiKey

* **类型**: string
* **说明**: 必须是合法 UUID；计费开启时（默认开启）必填，且账户积分需**大于 1**

## 响应格式

### 成功响应 (200)

```json
{
  "code": 0,
  "message": "成功",
  "data": {
    "texts": ["多谢", "请入席吧"],
    "timelines": [
      { "start": 2810000, "end": 3330000 },
      { "start": 4889000, "end": 6009000 }
    ],
    "words": ["多", "谢", "请", "入", "席", "吧"],
    "words_timelines": [
      { "start": 2810000, "end": 3070000 },
      { "start": 3070000, "end": 3330000 },
      { "start": 4889000, "end": 5320000 },
      { "start": 5320000, "end": 5620000 },
      { "start": 5620000, "end": 5860000 },
      { "start": 5860000, "end": 6009000 }
    ]
  }
}
```

### 响应字段说明

| 字段名 | 类型 | 说明 |
|--------|------|------|
| code | int | 0 表示成功，非 0 见下方错误码说明 |
| message | string | 提示信息，默认中文，带 `Accept-Language: en` 时返回英文 |
| data.texts | array | 对齐后的字幕文本列表，每行一条，**不含标点** |
| data.timelines | array | 与 `texts` 一一对应的行级时间线，**单位微秒** |
| data.timelines\[].start | int | 开始时间（微秒） |
| data.timelines\[].end | int | 结束时间（微秒） |
| data.words | array | **音频识别出的字**，按顺序排列（不是用户文本切出来的字） |
| data.words\_timelines | array | 与 `words` 一一对应的字级时间线，**单位微秒** |

### 错误响应

```json
{
  "code": 2003,
  "message": "下载文件失败"
}
```

错误体**不包含** `data` 字段；所有错误都返回 HTTP 200，需按 `code` 判断成功与否。

## 使用示例

### cURL 示例

```bash
curl -X POST https://autosubrt.jcaigc.cn/openapi/autosubrt/v1/asr/text/align \
  -H "Content-Type: application/json" \
  -d '{
    "audio_url": "https://example.com/audio.mp3",
    "text": "多谢，请入席吧。",
    "max_chars_per_line": 15,
    "apiKey": "123e4567-e89b-12d3-a456-426614174000"
  }'
```

### Python 示例

```python
import requests

resp = requests.post(
    "https://autosubrt.jcaigc.cn/openapi/autosubrt/v1/asr/text/align",
    json={
        "audio_url": "https://example.com/audio.mp3",
        "text": "多谢，请入席吧。",
        "max_chars_per_line": 15,
        "apiKey": "123e4567-e89b-12d3-a456-426614174000",
    },
    timeout=600,
)

result = resp.json()
if result["code"] != 0:
    raise RuntimeError(result["message"])

for line, timeline in zip(result["data"]["texts"], result["data"]["timelines"]):
    # 时间线单位是微秒，可直接用于剪映小助手 add_captions 的 start / end
    print(f"{timeline['start'] / 1e6:.2f}s - {timeline['end'] / 1e6:.2f}s  {line}")
```

## 计费

本接口按**音频时长**扣费，与剪映小助手共用同一套积分体系。

| 项 | 说明 |
| --- | --- |
| 单价 | **0.00022 积分 / 秒** |
| 计费依据 | 音频实际时长（秒），由识别引擎给出 |
| 扣费时机 | 音频下载并识别完成之后才扣费；**没有识别到语音也会按实际时长扣费** |
| 余额门槛 | 调用前账户积分需**大于 1**，否则直接拒绝（2035） |

| 音频时长 | 费用（积分） |
| --- | --- |
| 10 秒 | 0.002200 |
| 60 秒 | 0.013200 |
| 1 小时 | 0.792000 |

`apiKey` 必须是合法 UUID，可登录 <https://jcaigc.cn> 获取。

## 错误码说明

| 错误码 | 错误信息 | 说明 | 解决方案 |
|--------|----------|------|----------|
| 1001 | 参数校验失败 | 缺少 audio\_url 或 text，或 apiKey 不是合法 UUID | 检查请求参数 |
| 2001 | 识别音频失败 | 音频无法解码、模型未加载，或 audio\_url 返回 401/403/404 | 换一个可正常播放的文件或可访问的直链 |
| 2002 | 文件大小超出限制 | 音频超过 100MB | 压缩或截取后再试 |
| 2003 | 下载文件失败 | 下载过程中网络或服务端错误，重试后仍失败 | 确认是公网可直链下载的地址 |
| 2005 | 下载文件超时 | 下载整体超时 | 换更快的源或更小的文件 |
| 2035 | 账户余额不足 | 账户积分需大于 1 才可继续使用服务 | 完成充值后重试 |
| 2036 | 无效的 apiKey | 计费开启时未传 apiKey | 登录 https://jcaigc.cn 获取 apiKey |
| 9997 | 服务器忙 | 并发已达上限，请求未排队 | 稍后重试 |
| 9998 | 系统内部错误 | 未预期的内部异常 | 联系技术支持 |
| 9999 | 未知异常 | 积分服务不可用等 | 稍后重试 |

## 注意事项

1. **时间单位是微秒**（1 秒 = 1000000），与 [语音转文案](/docs/asr.zh)、[语音转 SRT 字幕](/docs/asr_srt.zh) 的毫秒不同。返回的时间线可直接用于剪映小助手 [add\_captions](/docs/add_captions.zh) 的 `start` / `end`。
2. **`texts` 不含标点**：切句时标点被去掉，需要带标点的文案请用 [语音转文案](/docs/asr.zh)。
3. **`words` 是音频识别出的字**，不是 `text` 切出来的字；它与 `words_timelines` 一一对应，可用来自行校准或做逐字高亮。
4. **文本与音频不一致时仍会返回结果**：对齐用的是编辑距离，文本比音频多出或少掉的字会被跳过或按比例摊到相邻区间，时间线只能保证大致贴合。
5. **没有识别到语音**时返回 `texts = [原始文本]`、`timelines = [{start: 0, end: 30000000}]`（30 秒占位）、`words` 与 `words_timelines` 为空数组，调用方需自行判断这种兜底结果。
6. **重复调用会重复扣费**，超时后请勿盲目重试。

## 工作流程

1. 校验 apiKey 与账户余额（计费开启时）
2. 下载 `audio_url` 指向的音视频到服务端临时目录
3. 语音识别，得到逐字时间线
4. 按标点切句、按 `max_chars_per_line` 拆行，用编辑距离把文本字与识别字对齐
5. 计算行级时间线，并用字级时间线做全局校准
6. 识别完成后按音频时长扣费
7. 返回文本、行级时间线与字级时间线，删除临时文件

## 相关接口

* [语音转文案](/docs/asr.zh)
* [语音转文本](/docs/asr_text.zh)
* [语音转 SRT 字幕](/docs/asr_srt.zh)

***

📚 **项目资源**\
**GitHub**: <https://github.com/Hommy-master/autosubrt>
