feat: 添加音频转文字功能及ASR配置

This commit is contained in:
cc 2026-03-27 19:22:48 +08:00
parent a191760e87
commit 80874f6e07
5 changed files with 1842 additions and 0 deletions

View File

@ -185,3 +185,44 @@ export const QUESTION_VARIANT_PROMPT = `你是一位专业的英语试题出题
export const IMAGE_MAX_SIZE_MB = 10;
export const IMAGE_ALLOWED_TYPES_ESSAY = ["image/jpeg", "image/jpg", "image/png"];
export const IMAGE_ALLOWED_TYPES_EXAM = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
// ── 阿里云百炼 ASR音频转文字──
export const BAILIAN_API_KEY = "sk-74fa3459e6a84dda85135fcbb4cf0f29"; // 请替换为您的阿里云百炼 API Key
export const BAILIAN_ASR_SUBMIT_URL = "/dashscope-api/api/v1/services/audio/asr/transcription"; // 使用代理路径避免跨域
export const BAILIAN_ASR_QUERY_BASE_URL = "/dashscope-api/api/v1/tasks"; // 使用代理路径避免跨域
export const BAILIAN_ASR_MODEL = "fun-asr";
// ── 音频文本优化接口(使用豆包模型)──
export const AUDIO_TEXT_OPTIMIZE_API_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
export const AUDIO_TEXT_OPTIMIZE_MODEL = "doubao-seed-2-0-lite-260215";
export const AUDIO_TEXT_OPTIMIZE_TEMPERATURE = 0.7;
export const AUDIO_TEXT_OPTIMIZE_MAX_TOKENS = 4096;
// 音频文本优化 System Prompt
export const AUDIO_TEXT_OPTIMIZE_PROMPT = `你是一位专业的文字编辑和排版专家。请对用户提供的语音识别文本进行分析和优化排版。
任务目标
将原始的语音识别文本转化为结构清晰易读性强的纯文本格式
优化规则
1. 分段处理根据语义和话题变化合理划分段落段落之间用空行分隔
2. 标点修正修正语音识别中可能错误的标点符号
3. 去除冗余删除重复内容无意义的语气词"嗯""啊""那个"
4. 格式优化
- 为不同主题添加小标题使用标题标题格式
- 重点内容前后可加空格或使用书名号标注
- 列表内容使用序号 1. 2. 3. 符号
5. 语义连贯确保句子和段落之间的逻辑连贯性
6. 保留原意严格保留原文的核心意思不做内容性修改
输出格式
请直接输出优化后的纯文本使用空行和符号来增强可读性
- 小标题使用标题标题格式
- 列表使用 1. 2. 3. 符号
- 分隔线可使用
- 不要使用任何 Markdown 语法 **##>
重要
- 只输出优化后的文本不要添加"优化后文本:"等前缀
- 保持原文语言中文/英文/日语
- 如果原文已经很好只需做必要的格式调整`;

609
src/md/alibailian-asr.md Normal file
View File

@ -0,0 +1,609 @@
本文介绍FunAudio-ASR录音文件识别RESTful API的参数和接口细节。
**用户指南:**关于模型介绍和选型建议请参见[录音文件识别-Fun-ASR/Paraformer/SenseVoice](https://help.aliyun.com/zh/model-studio/recording-file-recognition)。
目前提供了[提交任务接口](#418f2ac8ecxm4)和[查询任务接口](#480630e0582sb),通常情况下,您可以先调用提交任务接口上传识别任务,然后循环调用查询任务接口,直至任务完成。
## **前提条件**
已开通服务并[获取API Key](https://help.aliyun.com/zh/model-studio/get-api-key)。请[配置API Key到环境变量](https://help.aliyun.com/zh/model-studio/configure-api-key-through-environment-variables),而非硬编码在代码中,防范因代码泄露导致的安全风险。
**说明**
当您需要为第三方应用或用户提供临时访问权限,或者希望严格控制敏感数据访问、删除等高风险操作时,建议使用[临时鉴权Token](https://help.aliyun.com/zh/model-studio/generate-temporary-api-key)。
与长期有效的 API Key 相比,临时鉴权 Token 具备时效性短60秒、安全性高的特点适用于临时调用场景能有效降低API Key泄露的风险。
使用方式:在代码中,将原本用于鉴权的 API Key 替换为获取到的临时鉴权 Token 即可。
## **模型列表**
### 中国内地
在[中国内地部署模式](https://help.aliyun.com/zh/model-studio/regions/#080da663a75xh)下,接入点与数据存储均位于**北京地域**,模型推理计算资源仅限于中国内地。
| **模型名称** | **版本** | **单价** | **免费额度**[**(注)**](https://help.aliyun.com/zh/model-studio/new-free-quota#591f3dfedfyzj) |
| --- | --- | --- | --- |
| fun-asr > 当前等同fun-asr-2025-11-07 | 稳定版 | 0.00022元/秒 | 36,000秒10小时 有效期阿里云百炼开通后90天 |
| fun-asr-2025-11-07 > 相较fun-asr-2025-08-25做了远场VAD优化识别更准 | 快照版 |
| fun-asr-2025-08-25 |
| fun-asr-mtl > 当前等同fun-asr-mtl-2025-08-25 | 稳定版 |
| fun-asr-mtl-2025-08-25 | 快照版 |
- **支持的语种**
- fun-asr、fun-asr-2025-11-07中文普通话、粤语、吴语、闽南语、客家话、赣语、湘语、晋语并支持中原、西南、冀鲁、江淮、兰银、胶辽、东北、北京、港台等包括河南、陕西、湖北、四川、重庆、云南、贵州、广东、广西、河北、天津、山东、安徽、南京、江苏、杭州、甘肃、宁夏等地区官话口音、英文、日语
- fun-asr-2025-08-25中文普通话、英文
- fun-asr-mtl、fun-asr-mtl-2025-08-25中文普通话、粤语、英文、日语、韩语、越南语、印尼语、泰语、马来语、菲律宾语、阿拉伯语、印地语、保加利亚语、克罗地亚语、捷克语、丹麦语、荷兰语、爱沙尼亚语、芬兰语、希腊语、匈牙利语、爱尔兰语、拉脱维亚语、立陶宛语、马耳他语、波兰语、葡萄牙语、罗马尼亚语、斯洛伐克语、斯洛文尼亚语、瑞典语
- **支持的采样率**:任意
- **支持的音频格式**aac、amr、avi、flac、flv、m4a、mkv、mov、mp3、mp4、mpeg、ogg、opus、wav、webm、wma、wmv
### **国际**
在[国际部署模式](https://help.aliyun.com/zh/model-studio/regions/#080da663a75xh)下,接入点与数据存储均位于**新加坡地域**,模型推理计算资源在全球范围内动态调度(不含中国内地)。
| **模型名称** | **版本** | **单价** | **免费额度**[**(注)**](https://help.aliyun.com/zh/model-studio/new-free-quota#591f3dfedfyzj) |
| --- | --- | --- | --- |
| fun-asr > 当前等同fun-asr-2025-11-07 | 稳定版 | 0.00026元/秒 | 无免费额度 |
| fun-asr-2025-11-07 > 相较fun-asr-2025-08-25做了远场VAD优化识别更准 | 快照版 |
| fun-asr-2025-08-25 |
| fun-asr-mtl > 当前等同fun-asr-mtl-2025-08-25 | 稳定版 |
| fun-asr-mtl-2025-08-25 | 快照版 |
- **支持的语种**
- fun-asr、fun-asr-2025-11-07中文普通话、粤语、吴语、闽南语、客家话、赣语、湘语、晋语并支持中原、西南、冀鲁、江淮、兰银、胶辽、东北、北京、港台等包括河南、陕西、湖北、四川、重庆、云南、贵州、广东、广西、河北、天津、山东、安徽、南京、江苏、杭州、甘肃、宁夏等地区官话口音、英文、日语
- fun-asr-2025-08-25中文普通话、英文
- fun-asr-mtl、fun-asr-mtl-2025-08-25中文普通话、粤语、英文、日语、韩语、越南语、印尼语、泰语、马来语、菲律宾语、阿拉伯语、印地语、保加利亚语、克罗地亚语、捷克语、丹麦语、荷兰语、爱沙尼亚语、芬兰语、希腊语、匈牙利语、爱尔兰语、拉脱维亚语、立陶宛语、马耳他语、波兰语、葡萄牙语、罗马尼亚语、斯洛伐克语、斯洛文尼亚语、瑞典语
- **支持的采样率**:任意
- **支持的音频格式**aac、amr、avi、flac、flv、m4a、mkv、mov、mp3、mp4、mpeg、ogg、opus、wav、webm、wma、wmv
## **约束**
服务**不支持本地音视频文件直传也不支持base64格式音频**,输入源需为**可通过公网访问的文件URL**支持HTTP/HTTPS协议示例`https://your-domain.com/file.mp3`)。
使用SDK时若录音文件存储在[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8),不支持使用以 `oss://`为前缀的临时 URL。
使用RESTful API时若录音文件存储在[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8),支持使用以 `oss://`为前缀的临时 URL
**重要**
- 临时 URL 有效期48小时过期后无法使用**请勿用于生产环境。**
- 文件上传凭证接口限流为 100 QPS 且不支持扩容,**请勿用于生产环境、高并发及压测场景。**
- 生产环境建议使用[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/what-is-oss) 等稳定存储,确保文件长期可用并规避限流问题。
URL通过`file_urls`参数指定单次请求最多支持100个URL。
- **音频格式**
`aac`、`amr`、`avi`、`flac`、`flv`、`m4a`、`mkv`、`mov`、`mp3`、`mp4`、`mpeg`、`ogg`、`opus`、`wav`、`webm`、`wma`、`wmv`
**重要**
由于音视频格式及其变种众多技术上无法穷尽测试API不能保证所有格式均能够被正确识别。请通过测试验证您所提供的文件能够获得正常的语音识别结果。
- **音频采样率:**任意
- **音频文件大小和时长**
音频文件不超过2GB时长在12小时以内。
如果希望处理的文件超过了上述限制,可尝试对文件进行预处理以降低文件尺寸。有关文件预处理的最佳实践可以查阅[预处理视频文件以提高文件转写效率(针对录音文件识别场景)](https://help.aliyun.com/zh/model-studio/paraformer-best-practices#c5dda0a0cf2x9)。
- **批处理音频数目**
单次请求最多支持100个文件URL。
- **可识别语言:**fun-asr 支持中文、英文fun-asr-mtl-2025-08-25 支持中文, 粤语、英文、日语、 泰语、 越南语、印尼语。
- **接口调用方式限制**
不支持前端直接调用API需通过后端中转。
## **提交任务接口**
### **基本信息**
| **接口描述** | 提交语音识别任务。 |
| --- | --- |
| **URL** | ``` https://dashscope.aliyuncs.com/api/v1/services/audio/asr/transcription ``` |
| **请求方法** | POST |
| **请求头** | ``` Authorization: Bearer {api-key} // 需替换为您自己的API Key Content-Type: application/json X-DashScope-Async: enable // 请勿遗漏该请求头,否则无法提交任务 ``` |
| **消息体** | 包含所有[请求参数](#493b0f8f2ap0y)的消息体如下,对于可选字段,在实际业务中可根据需求省略: ``` { "model":"fun-asr", //模型名,必选 "input":{ "file_urls":[ "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav", "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_male2.wav" ] //待识别文件,必选 }, "parameters":{ "channel_id":[ 0 ], //音轨索引,可选 "special_word_filter": "xxx", //敏感词,可选 "diarization_enabled":false, //自动说话人分离,可选 "speaker_count": 2 //说话人数量参考,可选 } } ``` |
### **请求参数**
**点击查看请求示例**
以下为调用提交任务接口的cURL示例
```
# ======= 重要提示 =======
# 以下为北京地域url若使用新加坡地域的模型需将url替换为https://dashscope-intl.aliyuncs.com/api/v1/services/audio/asr/transcription
# 新加坡地域和北京地域的API Key不同。获取API Keyhttps://help.aliyun.com/zh/model-studio/get-api-key
# === 执行时请删除该注释 ===
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/audio/asr/transcription' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header "Content-Type: application/json" \
--header "X-DashScope-Async: enable" \
--data '{"model":"fun-asr","input":{"file_urls":["https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav",
"https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_male2.wav"]},"parameters":{"channel_id":[0]}}'
```
| **参数** | **类型** | **默认值** | **是否必须** | **说明** |
| --- | --- | --- | --- | --- |
| model | string | \\- | 是 | 指定用于音视频文件转写的模型名。参见[模型列表](#47e6ae42d1u1b)。 |
| file\\_urls | array\\[string\\] | \\- | 是 | 音视频文件转写的URL列表支持HTTP / HTTPS协议单次请求最多支持100个URL。 若录音文件存储在阿里云OSS使用RESTful API方式支持使用以 oss://为前缀的临时 URL。 **重要** - 临时 URL 有效期48小时过期后无法使用**请勿用于生产环境。** - 文件上传凭证接口限流为 100 QPS 且不支持扩容,**请勿用于生产环境、高并发及压测场景。** - 生产环境建议使用[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/what-is-oss) 等稳定存储,确保文件长期可用并规避限流问题。 |
| vocabulary\\_id | string | \\- | 否 | 热词ID此次语音识别中生效此热词ID对应的热词信息。默认不启用。使用方法请参考[定制热词](https://help.aliyun.com/zh/model-studio/custom-hot-words/)。 |
| channel\\_id | array\\[integer\\] | \\[0\\] | 否 | 指定在多音轨音频文件中需要识别的音轨索引,索引从 0 开始。例如,\\[0\\] 表示识别第一个音轨,\\[0, 1\\] 表示同时识别第一和第二个音轨。如果省略此参数,则默认处理第一个音轨。 **重要** 指定的每一个音轨都将独立计费。例如,为单个文件请求 \\[0, 1\\] 会产生两笔独立的费用。 |
| special\\_word\\_filter | string | \\- | 否 | 指定在语音识别过程中需要处理的敏感词,并支持对不同敏感词设置不同的处理方式。 若未传入该参数,系统将启用系统内置的敏感词过滤逻辑,识别结果中与[阿里云百炼敏感词表](https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/%E7%99%BE%E7%82%BC%E6%95%8F%E6%84%9F%E8%AF%8D%E5%88%97%E8%A1%A8_20230716.words.txt)匹配的词语将被替换为等长的`*`。 若传入该参数,则可实现以下敏感词处理策略: - 替换为 `*`:将匹配的敏感词替换为等长的 `*` - 直接过滤:将匹配的敏感词从识别结果中完全移除。 该参数的值应为一个 JSON 字符串,其结构如下所示: ``` { "filter_with_signed": { "word_list": ["测试"] }, "filter_with_empty": { "word_list": ["开始", "发生"] }, "system_reserved_filter": true } ``` JSON字段说明 - `filter_with_signed` - 类型:对象。 - 是否必填:否。 - 描述:配置需替换为`*`的敏感词列表。识别结果中匹配的词语将被等长的 `*` 替代。 - 示例以上述JSON为例“帮我测试一下这段代码”的语音识别结果将会是“帮我\\*\\*一下这段代码”。 - 内部字段: - `word_list`: 字符串数组,列出需被替换的敏感词。 - `filter_with_empty` - 类型:对象。 - 是否必填:否。 - 描述:配置需从识别结果中移除(过滤)的敏感词列表。识别结果中匹配的词语将被完全删除。 - 示例以上述JSON为例“比赛这就要开始了吗”的语音识别结果将会是“比赛这就要了吗”。 - 内部字段: - `word_list`: 字符串数组,列出需被完全移除(过滤)的敏感词。 - `system_reserved_filter` - 类型:布尔值。 - 是否必填:否。 - 默认值true。 - 描述:是否启用系统预置的敏感词规则。设为`true`时,将同时启用系统内置的敏感词过滤逻辑,识别结果中与[阿里云百炼敏感词表](https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/%E7%99%BE%E7%82%BC%E6%95%8F%E6%84%9F%E8%AF%8D%E5%88%97%E8%A1%A8_20230716.words.txt)匹配的词语将被替换为等长的`*`。 |
| diarization\\_enabled | boolean | false | 否 | 自动说话人分离,默认关闭。 仅适用于单声道音频,多声道音频不支持说话人分离。 启用该功能后,识别结果中将显示`speaker_id`字段,用于区分不同说话人。 有关`speaker_id`的示例,请参见[识别结果说明](#5882b67243tcg)。 |
| speaker\\_count | integer | \\- | 否 | 说话人数量参考值。取值范围为2至100的整数包含2和100。 开启说话人分离功能后diarization\\_enabled设置为true生效。 默认自动判断说话人数量,如果配置此项,只能辅助算法尽量输出指定人数,无法保证一定会输出此人数。 |
| language\\_hints | array\\[string\\] | \\- | 否 | 设置待识别语言代码。如果无法提前确定语种,可不设置,模型会自动识别语种。 系统仅读取数组中的首个值。多余值将被忽略。 不同模型支持的语言代码如下: - fun-asr、fun-asr-2025-11-07 - zh: 中文 - en: 英文 - ja: 日语 - fun-asr-2025-08-25 - zh: 中文 - en: 英文 - fun-asr-mtl、fun-asr-mtl-2025-08-25 - zh: 中文 - en: 英文 - ja: 日语 - ko韩语 - vi越南语 - id印尼语 - th泰语 - ms马来语 - tl菲律宾语 - ar阿拉伯语 - hi印地语 - bg保加利亚语 - hr克罗地亚语 - cs捷克语 - da丹麦语 - nl荷兰语 - et爱沙尼亚语 - fi芬兰语 - el希腊语 - hu匈牙利语 - ga爱尔兰语 - lv拉脱维亚语 - lt立陶宛语 - mt马耳他语 - pl波兰语 - pt葡萄牙语 - ro罗马尼亚语 - sk斯洛伐克语 - sl斯洛文尼亚语 - sv瑞典语 |
### **响应参数**
**点击查看响应示例**
```
{
"output": {
"task_status": "PENDING",
"task_id": "c2e5d63b-96e1-4607-bb91-************"
},
"request_id": "77ae55ae-be17-97b8-9942--************"
}
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| task\\_status | string | 任务状态。 |
| task\\_id | string | 任务ID。该ID在[查询任务接口](#480630e0582sb)中作为[请求参数](#0634617fe8jqg)传入。 |
## **查询任务接口**
### **基本信息**
| **接口描述** | 查询语音识别任务执行情况和结果。 |
| --- | --- |
| **URL** | ``` https://dashscope.aliyuncs.com/api/v1/tasks/{task_id} ``` |
| **请求方法** | POST |
| **请求头** | ``` Authorization: Bearer {api-key} // 需替换为您自己的API Key ``` |
| **消息体** | 无。 |
### **请求参数**
**点击查看请求示例**
以下为调用查询任务接口的cURL示例
```
curl --location 'https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}' --header "Authorization: Bearer $DASHSCOPE_API_KEY"
```
| **参数** | **类型** | **默认值** | **是否必须** | **说明** |
| --- | --- | --- | --- | --- |
| task\\_id | string | \\- | 是 | 查询任务需指定其ID该ID为[提交任务接口](#418f2ac8ecxm4)被调用后返回的`task_id`。 |
### **响应参数**
**点击查看响应示例**
当任务包含多个子任务时,只要存在任一子任务成功,整个任务状态将标记为`SUCCEEDED`,需通过`subtask_status`字段判断具体子任务结果。
## 正常示例
```
{
"request_id": "f9e1afad-94d3-997e-a83b-************",
"output": {
"task_id": "f86ec806-4d73-485f-a24f-************",
"task_status": "SUCCEEDED",
"submit_time": "2024-09-12 15:11:40.041",
"scheduled_time": "2024-09-12 15:11:40.071",
"end_time": "2024-09-12 15:11:40.903",
"results": [
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_male2.wav",
"transcription_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/pre/filetrans-16k/20240912/15%3A11/3bdf7689-b598-409d-806a-121cff5e4a31-1.json?Expires=1726211500&OSSAccessKeyId=yourOSSAccessKeyId&Signature=Fj%2BaF%2FH0Kayj3w3My2ECBeP****%3D",
"subtask_status": "SUCCEEDED"
},
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav",
"transcription_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/pre/filetrans-16k/20240912/15%3A11/409a4b92-445b-4dd8-8c1d-f110954d82d8-1.json?Expires=1726211500&OSSAccessKeyId=yourOSSAccessKeyId&Signature=v5Owy5qoAfT7mzGmQgH0g8C****%3D",
"subtask_status": "SUCCEEDED"
}
],
"task_metrics": {
"TOTAL": 2,
"SUCCEEDED": 2,
"FAILED": 0
}
},
"usage": {
"duration": 9
}
}
```
## 异常示例
“`code`”为错误码,“`message`”为错误信息,只有异常情况才有这两个字段,您可以通过这两个字段,对照[错误码](#1dd0e8e854p6w)排查问题。
```
{
"task_id": "7bac899c-06ec-4a79-8875-xxxxxxxxxxxx",
"task_status": "SUCCEEDED",
"submit_time": "2024-12-16 16:30:59.170",
"scheduled_time": "2024-12-16 16:30:59.204",
"end_time": "2024-12-16 16:31:02.375",
"results": [
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/long_audio_demo_cn.mp3",
"transcription_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/prod/paraformer-v2/20241216/xxxx",
"subtask_status": "SUCCEEDED"
},
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/rich_text_exaple_1.wav",
"code": "InvalidFile.DownloadFailed",
"message": "The audio file cannot be downloaded.",
"subtask_status": "FAILED"
}
],
"task_metrics": {
"TOTAL": 2,
"SUCCEEDED": 1,
"FAILED": 1
}
}
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| task\\_id | string | 被查询任务的ID。 |
| task\\_status | string | 被查询任务的状态。 **说明** 当任务包含多个子任务时,只要存在任一子任务成功,整个任务状态将标记为`SUCCEEDED`,需通过`subtask_status`字段判断具体子任务结果。 |
| subtask\\_status | string | 子任务状态。 |
| file\\_url | string | 文件转写任务中所处理的文件URL。 |
| transcription\\_url | string | 获取识别结果对应的链接。该链接有效期为24小时超时后无法查询任务或通过先前查询结果中的URL下载结果。 识别结果保存为JSON文件您可以通过上述链接下载该文件或直接通过HTTP请求读取该文件中的内容。 JSON数据中各字段含义请参见[识别结果说明](#5882b67243tcg)。 |
### 识别结果说明
识别结果保存为JSON文件。
点击查看识别结果示例
```
{
"file_url":"https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav",
"properties":{
"audio_format":"pcm_s16le",
"channels":[
0
],
"original_sampling_rate":16000,
"original_duration_in_milliseconds":3834
},
"transcripts":[
{
"channel_id":0,
"content_duration_in_milliseconds":3720,
"text":"Hello world, 这里是阿里巴巴语音实验室。",
"sentences":[
{
"begin_time":100,
"end_time":3820,
"text":"Hello world, 这里是阿里巴巴语音实验室。",
"sentence_id":1,
"speaker_id":0, //当开启自动说话人分离功能时才会显示该字段
"words":[
{
"begin_time":100,
"end_time":596,
"text":"Hello ",
"punctuation":""
},
{
"begin_time":596,
"end_time":844,
"text":"world",
"punctuation":", "
}
// 这里省略其它内容
]
}
]
}
]
}
```
需要关注的参数如下:
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| audio\\_format | string | 源文件中音频的格式。 |
| channels | array\\[integer\\] | 源文件中音频的音轨索引信息,对单轨音频返回\\[0\\],对双轨音频返回\\[0, 1\\],以此类推。 |
| original\\_sampling\\_rate | integer | 源文件中音频的采样率Hz。 |
| original\\_duration\\_in\\_milliseconds | integer | 源文件中的原始音频时长ms。 |
| channel\\_id | integer | 转写结果的音轨索引以0为起始。 |
| content\\_duration | integer | 音轨中被判定为语音内容的时长ms**重要** 语音识别模型服务仅对音轨中被判定为语音内容的时长进行语音转写并据此进行计量计费非语音内容不计量、不计费。通常情况下语音内容时长会短于原始音频时长。由于对是否存在语音内容的判定是由AI模型给出的可能与实际情况存在一定误差。 |
| transcript | string | 段落级别的语音转写结果。 |
| sentences | array | 句子级别的语音转写结果。 |
| words | array | 词级别的语音转写结果。 |
| begin\\_time | integer | 开始时间戳ms。 |
| end\\_time | integer | 结束时间戳ms。 |
| text | string | 语音转写结果。 |
| speaker\\_id | integer | 当前说话人的索引以0为起始用于区分不同的说话人。 仅在启用说话人分离功能时,该字段才会显示于识别结果中。 |
| punctuation | string | 预测出的词之后的标点符号(如有)。 |
## **其他接口:批量查询任务状态/取消任务**
详情请参见[管理异步任务](https://help.aliyun.com/zh/model-studio/manage-asynchronous-tasks)支持批量查询24小时内提交的录音文件识别任务同时支持取消`PENDING`(排队)状态的任务。
## **完整示例**
您可以使用编程语言自带的HTTP类库来实现提交和查询任务的请求先调用提交任务接口上传识别任务然后循环调用查询任务接口直至任务完成。
以Python为例代码如下
```
import requests
import json
import os
import time
# 若没有配置环境变量请用百炼API Key将下行替换为api_key = "sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY")
file_urls = [
"https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav",
"https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_male2.wav",
]
# 提交文件转写任务包含待转写文件url列表
def submit_task(apikey, file_urls) -> str:
headers = {
"Authorization": f"Bearer {apikey}",
"Content-Type": "application/json",
"X-DashScope-Async": "enable",
}
data = {
"model": "fun-asr",
"input": {"file_urls": file_urls},
"parameters": {
"channel_id": [0]
},
}
# 录音文件转写服务url
service_url = (
"https://dashscope.aliyuncs.com/api/v1/services/audio/asr/transcription"
)
response = requests.post(
service_url, headers=headers, data=json.dumps(data)
)
# 打印响应内容
if response.status_code == 200:
return response.json()["output"]["task_id"]
else:
print("task failed!")
print(response.json())
return None
# 循环查询任务状态直到成功
def wait_for_complete(task_id):
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"X-DashScope-Async": "enable",
}
pending = True
while pending:
# 查询任务状态服务url
service_url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
response = requests.post(
service_url, headers=headers
)
if response.status_code == 200:
status = response.json()['output']['task_status']
if status == 'SUCCEEDED':
print("task succeeded!")
pending = False
return response.json()['output']['results']
elif status == 'RUNNING' or status == 'PENDING':
pass
else:
print("task failed!")
pending = False
else:
print("query failed!")
pending = False
print(response.json())
time.sleep(0.1)
task_id = submit_task(apikey=api_key, file_urls=file_urls)
print("task_id: ", task_id)
result = wait_for_complete(task_id)
print("transcription result: ", result)
```
## **错误码**
如遇报错问题,请参见[错误信息](https://help.aliyun.com/zh/model-studio/error-code)进行排查。
当任务包含多个子任务时,只要存在任一子任务成功,整个任务状态将标记为`SUCCEEDED`,需通过`subtask_status`字段判断具体子任务结果。
错误返回示例:
```
{
"task_id": "7bac899c-06ec-4a79-8875-xxxxxxxxxxxx",
"task_status": "SUCCEEDED",
"submit_time": "2024-12-16 16:30:59.170",
"scheduled_time": "2024-12-16 16:30:59.204",
"end_time": "2024-12-16 16:31:02.375",
"results": [
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/long_audio_demo_cn.mp3",
"transcription_url": "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/prod/paraformer-v2/20241216/xxxx",
"subtask_status": "SUCCEEDED"
},
{
"file_url": "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/rich_text_exaple_1.wav",
"code": "InvalidFile.DownloadFailed",
"message": "The audio file cannot be downloaded.",
"subtask_status": "FAILED"
}
],
"task_metrics": {
"TOTAL": 2,
"SUCCEEDED": 1,
"FAILED": 1
}
}
```
## **常见问题**
### **功能特性**
#### **Q是否支持Base64编码方式的音频**
不支持Base64编码方式的音频。仅支持可通过公网访问的 URL 所指向的音频的识别,不支持识别二进制流,也不支持直接识别本地文件。
#### **Q如何将音频文件以公网可访问的URL形式提供**
通常遵循以下几个步骤(这里为您提供一种思路,具体情况因不同存储产品而异,推荐将音频[上传至阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8)
1、选择存储和托管方式
如以下这几种:
- 对象存储服务(推荐):
- 使用云服务商的对象存储服务(如[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8)),将音频文件上传到存储桶中,并设置为公开访问。
- 优点:高可用性、支持 CDN 加速、易于管理。
- Web 服务器:
- 将音频文件放置在支持 HTTP/HTTPS 访问的 Web 服务器上(如 Nginx、Apache
- 优点:适合小型项目或本地测试。
- 内容分发网络CDN
- 将音频文件托管在 CDN 上,通过 CDN 提供的 URL 访问。
- 优点:加速文件传输,适合高并发场景。
2、上传音频文件
根据选择的存储/托管方式,将音频上传,如:
- 对象存储服务:
- 登录云服务商的控制台,创建存储桶。
- 上传音频文件,并设置文件权限为“公共读”或生成临时访问链接。
- Web 服务器:
- 将音频文件放置在服务器指定目录下(如 `/var/www/html/audio/`)。
- 确保文件可以通过 HTTP/HTTPS 访问。
3、生成公网可访问的URL
例如:
- 对象存储服务:
- 文件上传后,系统会自动生成一个公网访问 URL通常格式为 `https://<bucket-name>.<region>.aliyuncs.com/<file-name>`)。
- 如果需要更友好的域名,可以绑定自定义域名并开启 HTTPS。
- Web 服务器:
- 文件的访问 URL 通常是服务器地址加上文件路径(如 `https://your-domain.com/audio/file.mp3`)。
- CDN
- 配置 CDN 加速后,使用 CDN 提供的 URL `https://cdn.your-domain.com/audio/file.mp3`)。
4、验证URL的可用性
公网环境下,确保生成的 URL 可以正常访问,例如:
- 在浏览器中打开 URL检查是否能播放音频文件。
- 使用工具(如 `curl` 或 Postman验证 URL 是否返回正确的 HTTP 响应(状态码 200
使用SDK时若录音文件存储在[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8),不支持使用以 `oss://`为前缀的临时 URL。
使用RESTful API时若录音文件存储在[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/simple-upload#a632b50f190j8),支持使用以 `oss://`为前缀的临时 URL
**重要**
- 临时 URL 有效期48小时过期后无法使用**请勿用于生产环境。**
- 文件上传凭证接口限流为 100 QPS 且不支持扩容,**请勿用于生产环境、高并发及压测场景。**
- 生产环境建议使用[阿里云OSS](https://help.aliyun.com/zh/oss/user-guide/what-is-oss) 等稳定存储,确保文件长期可用并规避限流问题。
#### **Q多久能获取识别结果**
任务提交后将进入排队PENDING状态排队时间取决于队列长度和文件时长无法明确给出通常在数分钟内请耐心等待。并且音频时长越长所需时间越久。
### **故障排查**
如遇代码报错问题,请根据[错误码](#1dd0e8e854p6w)中的信息进行排查。
#### **Q录音文件URL设置成OSS临时公网访问不通该如何处理**
headers中将`X-DashScope-OssResourceResolve`设为`enable`。
不推荐该方式。
Java SDK或者Python SDK不支持对headers进行配置。
#### **Q一直轮询不到结果**
可能是限流原因,请耐心等待。
#### **Q无法识别语音无识别结果是什么原因**
请检查音频格式和采样率是否正确且符合参数约束。
可以使用[ffprobe](https://ffmpeg.org/ffprobe.html)工具获取音频的容器、编码、采样率、声道等信息:
```
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
```
/\* 让引用上下间距调小,避免内容显示过于稀疏 \*/ .unionContainer .markdown-body blockquote { margin: 4px 0; } .aliyun-docs-content table.qwen blockquote { border-left: none; /\* 添加这一行来移除表格里的引用文字的左侧边框 \*/ padding-left: 5px; /\* 左侧内边距 \*/ margin: 4px 0; }

View File

@ -8,6 +8,7 @@ import SpellPractice from '../views/SpellPractice.vue'
import ProblemSolving from '../views/ProblemSolving.vue'
import QuestionGenerator from '../views/QuestionGenerator.vue'
import QuestionVariant from '../views/QuestionVariant.vue'
import AudioToText from '../views/AudioToText.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -57,6 +58,11 @@ const router = createRouter({
name: 'question-variant',
component: QuestionVariant
},
{
path: '/audio-to-text',
name: 'audio-to-text',
component: AudioToText
},
]
})

1152
src/views/AudioToText.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,14 @@ const features = ref([
icon: "variant",
route: "/question-variant",
},
{
id: 10,
title: "音频转文字",
desc: "输入音频文件URLAI自动识别并转换为文本支持中英日多语种适用于会议记录、采访整理等场景。",
class: "card-10",
icon: "file-audio",
route: "/audio-to-text",
},
]);
// Hover effect for glassmorphism glare
@ -290,6 +298,27 @@ onUnmounted(() => {
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876v9.004c0 .621-.504 1.125-1.125 1.125h-3.75c-.621 0-1.125.504-1.125 1.125v3.876c0 .621.504 1.125 1.125 1.125h3.75c.621 0 1.125-.504 1.125-1.125Z"
/>
</svg>
<!-- File Audio Icon -->
<svg
v-else-if="feature.icon === 'file-audio'"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M11.25 12.75l2.25-1.5v4.5l-2.25-1.5v-1.5z"
/>
</svg>
</div>
<h2 class="card-title">{{ feature.title }}</h2>
</div>
@ -477,6 +506,11 @@ h1 {
box-shadow: 0 8px 20px -6px rgba(99, 102, 241, 0.5);
}
.card-10 .icon-wrapper {
background: linear-gradient(135deg, #06b6d4, #0891b2);
box-shadow: 0 8px 20px -6px rgba(6, 182, 212, 0.5);
}
.card-title {
font-size: 1.5rem;
font-weight: 600;