录音文件识别(也称为录音文件转写)是指对音视频文件进行语音识别,将语音转换为文本。支持单个文件识别和批量文件识别,适用于处理不需要即时返回结果的场景。
应用场景
会议、课堂录音记录:将录音文件转成文字,方便后期快速进行信息检索、分析和整理重点内容。
客服电话分析:自动记录并分析客户电话,快速理解客户需求,自动分类服务请求,甚至识别客户情绪,从而提升服务质量与效率。
字幕生成:帮助媒体制作与后期编辑人员识别音视频材料并生成对应的字幕,加速后期制作的流程。
市场研究与数据分析:将市场调研中收集到的消费者访谈、焦点小组讨论等录音数据,通过识别模型进行分析,提取消费者意见、偏好等信息,为企业决策提供支持。
支持的模型
模型选型建议
语种支持:
对于中文(普通话)、英语,建议优先选择Paraformer(最新版Paraformer-v2)或Fun-ASR模型以获得更优效果。
对于中文(方言)、粤语、日语、韩语、西班牙语、印尼语、法语、德语、意大利语、马来语,建议优先选择Paraformer模型。特别是最新版Paraformer-v2模型,它支持指定语种,包括中文(含普通话和多种方言)、粤语、英语、日语、韩语。指定语种后,系统能够集中算法资源和语言模型于该特定语种,避免了在多种可能的语种中进行猜测和切换,从而减少了误识别的概率。
对于其他语言(俄语、泰语等),请选择SenseVoice,具体请参见Java SDK。
文件读取方式:Fun-ASR、Paraformer和SenseVoice模型仅支持读取录音文件的URL。
热词定制:如果您的业务领域中,有部分专有名词和行业术语识别效果不够好,您可以定制热词,将这些词添加到词表从而改善识别结果。如需使用热词功能,请选择Paraformer或Fun-ASR模型。关于热词的更多信息,Paraformer v1系列模型请参见Paraformer语音识别热词定制与管理,Paraformer v2及更高版本模型或Fun-ASR模型请参见定制热词。
时间戳:如果您需要在获取识别结果的同时获取时间戳,请选择Fun-ASR、Paraformer或者SenseVoice模型。
情感和事件识别:如果需要情感识别能力(包括高兴
<HAPPY>
、伤心<SAD>
、生气<ANGRY>
和中性<NEUTRAL>
)和4种常见音频事件识别(包括背景音乐<BGM>
、说话声<Speech>
、掌声<Applause>
和笑声<Laughter>
),请选择SenseVoice语音识别模型。
在线体验
目前,仅以下录音文件识别模型支持在线体验:
paraformer-v2:在语音识别页面点击更多模型,选择“Paraformer语音识别-v2”
paraformer-8k-v1:在语音识别页面点击更多模型,选择“Paraformer语音识别-8k-v1”
paraformer-v1:在语音识别页面直接选择“Paraformer语音识别-v1”
paraformer-mtl-v1:在语音识别页面点击更多模型,选择“Paraformer语音识别-mtl-v1”
以下模型暂不支持在线体验,如需使用请通过API接入:
paraformer-8k-v2
fun-asr
fun-asr-2025-08-25
sensevoice-v1
快速开始
下面是调用API的示例代码。
您需要已获取API Key并配置API Key到环境变量。如果通过SDK调用,还需要安装DashScope SDK。
Paraformer
由于音视频文件的尺寸通常较大,文件传输和语音识别处理均需要时间,文件转写API通过异步调用方式来提交任务。开发者需要通过查询接口,在文件转写完成后获得语音识别结果。
Python
from http import HTTPStatus
from dashscope.audio.asr import Transcription
import json
# 若没有将API Key配置到环境变量中,需将下面这行代码注释放开,并将apiKey替换为自己的API Key
# import dashscope
# dashscope.api_key = "apiKey"
task_response = Transcription.async_call(
model='paraformer-v2',
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'],
language_hints=['zh', 'en'] # “language_hints”只支持paraformer-v2模型
)
transcribe_response = Transcription.wait(task=task_response.output.task_id)
if transcribe_response.status_code == HTTPStatus.OK:
print(json.dumps(transcribe_response.output, indent=4, ensure_ascii=False))
print('transcription done!')
Java
SenseVoice
由于音视频文件的尺寸通常较大,文件传输和语音识别处理均需要时间,文件转写API通过异步调用方式来提交任务。开发者需要通过查询接口,在文件转写完成后获得语音识别结果。
# For prerequisites running the following sample, visit https://help.aliyun.com/document_detail/611472.html
import re
import json
from urllib import request
from http import HTTPStatus
import dashscope
# 将your-dashscope-api-key替换成您自己的API-KEY
dashscope.api_key = 'your-dashscope-api-key'
def parse_sensevoice_result(data, keep_trans=True, keep_emotions=True, keep_events=True):
'''
本工具用于解析 sensevoice 识别结果
keep_trans: 是否保留转写文本,默认为True
keep_emotions: 是否保留情感标签,默认为True
keep_events: 是否保留事件标签,默认为True
'''
# 定义要保留的标签
emotion_list = ['NEUTRAL', 'HAPPY', 'ANGRY', 'SAD']
event_list = ['Speech', 'Applause', 'BGM', 'Laughter']
# 所有支持的标签
all_tags = ['Speech', 'Applause', 'BGM', 'Laughter',
'NEUTRAL', 'HAPPY', 'ANGRY', 'SAD', 'SPECIAL_TOKEN_1']
tags_to_cleanup = []
for tag in all_tags:
tags_to_cleanup.append(f'<|{tag}|> ')
tags_to_cleanup.append(f'<|/{tag}|>')
tags_to_cleanup.append(f'<|{tag}|>')
def get_clean_text(text: str):
for tag in tags_to_cleanup:
text = text.replace(tag, '')
pattern = r"\s{2,}"
text = re.sub(pattern, " ", text).strip()
return text
for item in data['transcripts']:
for sentence in item['sentences']:
if keep_emotions:
# 提取 emotion
emotions_pattern = r'<\|(' + '|'.join(emotion_list) + r')\|>'
emotions = re.findall(emotions_pattern, sentence['text'])
sentence['emotion'] = list(set(emotions))
if not sentence['emotion']:
sentence.pop('emotion', None)
if keep_events:
# 提取 event
events_pattern = r'<\|(' + '|'.join(event_list) + r')\|>'
events = re.findall(events_pattern, sentence['text'])
sentence['event'] = list(set(events))
if not sentence['event']:
sentence.pop('event', None)
if keep_trans:
# 提取纯文本
sentence['text'] = get_clean_text(sentence['text'])
else:
sentence.pop('text', None)
if keep_trans:
item['text'] = get_clean_text(item['text'])
else:
item.pop('text', None)
item['sentences'] = list(filter(lambda x: 'text' in x or 'emotion' in x or 'event' in x, item['sentences']))
return data
task_response = dashscope.audio.asr.Transcription.async_call(
model='sensevoice-v1',
file_urls=[
'https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/rich_text_example_1.wav'],
language_hints=['en'], )
print('task_id: ', task_response.output.task_id)
transcription_response = dashscope.audio.asr.Transcription.wait(
task=task_response.output.task_id)
if transcription_response.status_code == HTTPStatus.OK:
for transcription in transcription_response.output['results']:
if transcription['subtask_status'] == 'SUCCEEDED':
url = transcription['transcription_url']
result = json.loads(request.urlopen(url).read().decode('utf8'))
print(json.dumps(parse_sensevoice_result(result, keep_trans=False, keep_emotions=False), indent=4,
ensure_ascii=False))
else:
print('transcription failed!')
print(transcription)
print('transcription done!')
else:
print('Error: ', transcription_response.output.message)
package org.example.recognition;
import com.alibaba.dashscope.audio.asr.transcription.*;
import com.google.gson.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class SenseVoiceParser {
private static final List<String> EMOTION_LIST = Arrays.asList("NEUTRAL", "HAPPY", "ANGRY", "SAD");
private static final List<String> EVENT_LIST = Arrays.asList("Speech", "Applause", "BGM", "Laughter");
private static final List<String> ALL_TAGS = Arrays.asList(
"Speech", "Applause", "BGM", "Laughter", "NEUTRAL", "HAPPY", "ANGRY", "SAD", "SPECIAL_TOKEN_1");
/**
* 本工具用于解析 sensevoice 识别结果
* @param data json格式的sensevoice转写结果
* @param keepTrans 是否保留转写文本
* @param keepEmotions 是否保留情感标签
* @param keepEvents 是否保留事件标签
* @return
*/
public static JsonObject parseSenseVoiceResult(JsonObject data, boolean keepTrans, boolean keepEmotions, boolean keepEvents) {
List<String> tagsToCleanup = ALL_TAGS.stream()
.flatMap(tag -> Stream.of("<|" + tag + "|> ", "<|/" + tag + "|>", "<|" + tag + "|>"))
.collect(Collectors.toList());
JsonArray transcripts = data.getAsJsonArray("transcripts");
for (JsonElement transcriptElement : transcripts) {
JsonObject transcript = transcriptElement.getAsJsonObject();
JsonArray sentences = transcript.getAsJsonArray("sentences");
for (JsonElement sentenceElement : sentences) {
JsonObject sentence = sentenceElement.getAsJsonObject();
String text = sentence.get("text").getAsString();
if (keepEmotions) {
extractTags(sentence, text, EMOTION_LIST, "emotion");
}
if (keepEvents) {
extractTags(sentence, text, EVENT_LIST, "event");
}
if (keepTrans) {
String cleanText = getCleanText(text, tagsToCleanup);
sentence.addProperty("text", cleanText);
} else {
sentence.remove("text");
}
}
if (keepTrans) {
transcript.addProperty("text", getCleanText(transcript.get("text").getAsString(), tagsToCleanup));
} else {
transcript.remove("text");
}
JsonArray filteredSentences = new JsonArray();
for (JsonElement sentenceElement : sentences) {
JsonObject sentence = sentenceElement.getAsJsonObject();
if (sentence.has("text") || sentence.has("emotion") || sentence.has("event")) {
filteredSentences.add(sentence);
}
}
transcript.add("sentences", filteredSentences);
}
return data;
}
private static void extractTags(JsonObject sentence, String text, List<String> tagList, String key) {
String pattern = "<\\|(" + String.join("|", tagList) + ")\\|>";
Pattern compiledPattern = Pattern.compile(pattern);
Matcher matcher = compiledPattern.matcher(text);
Set<String> tags = new HashSet<>();
while (matcher.find()) {
tags.add(matcher.group(1));
}
if (!tags.isEmpty()) {
JsonArray tagArray = new JsonArray();
tags.forEach(tagArray::add);
sentence.add(key, tagArray);
} else {
sentence.remove(key);
}
}
private static String getCleanText(String text, List<String> tagsToCleanup) {
for (String tag : tagsToCleanup) {
text = text.replace(tag, "");
}
return text.replaceAll("\\s{2,}", " ").trim();
}
}
public class Main {
public static void main(String[] args) {
// 创建转写请求参数,需要用真实apikey替换your-dashscope-api-key
TranscriptionParam param =
TranscriptionParam.builder()
// 将your-dashscope-api-key替换成您自己的API-KEY
.apiKey("your-dashscope-api-key")
.model("sensevoice-v1")
.fileUrls(
Arrays.asList(
"https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/sensevoice/rich_text_example_1.wav"))
.parameter("language_hints", new String[] {"en"})
.build();
try {
Transcription transcription = new Transcription();
// 提交转写请求
TranscriptionResult result = transcription.asyncCall(param);
System.out.println("requestId: " + result.getRequestId());
// 等待转写完成
result = transcription.wait(
TranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
// 获取转写结果
List<TranscriptionTaskResult> taskResultList = result.getResults();
if (taskResultList != null && taskResultList.size() > 0) {
for (TranscriptionTaskResult taskResult : taskResultList) {
String transcriptionUrl = taskResult.getTranscriptionUrl();
HttpURLConnection connection =
(HttpURLConnection) new URL(transcriptionUrl).openConnection();
connection.setRequestMethod("GET");
connection.connect();
BufferedReader reader =
new BufferedReader(new InputStreamReader(connection.getInputStream()));
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement jsonResult = gson.fromJson(reader, JsonObject.class);
System.out.println(gson.toJson(jsonResult));
System.out.println(gson.toJson(SenseVoiceParser.parseSenseVoiceResult(jsonResult.getAsJsonObject(), true, true, true)));
}
}
} catch (Exception e) {
System.out.println("error: " + e);
}
System.exit(0);
}
}
Fun-ASR
由于音视频文件的尺寸通常较大,文件传输和语音识别处理均需要时间,文件转写API通过异步调用方式来提交任务。开发者需要通过查询接口,在文件转写完成后获得语音识别结果。
Python
from http import HTTPStatus
from dashscope.audio.asr import Transcription
import json
# 若没有将API Key配置到环境变量中,需将下面这行代码注释放开,并将apiKey替换为自己的API Key
# import dashscope
# dashscope.api_key = "apiKey"
task_response = Transcription.async_call(
model='fun-asr',
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']
)
transcribe_response = Transcription.wait(task=task_response.output.task_id)
if transcribe_response.status_code == HTTPStatus.OK:
print(json.dumps(transcribe_response.output, indent=4, ensure_ascii=False))
print('transcription done!')
Java
import com.alibaba.dashscope.audio.asr.transcription.*;
import com.google.gson.*;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 创建转写请求参数
TranscriptionParam param =
TranscriptionParam.builder()
// 若没有将API Key配置到环境变量中,需将apiKey替换为自己的API Key
//.apiKey("apikey")
.model("fun-asr")
.fileUrls(
Arrays.asList(
"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"))
.build();
try {
Transcription transcription = new Transcription();
// 提交转写请求
TranscriptionResult result = transcription.asyncCall(param);
System.out.println("RequestId: " + result.getRequestId());
// 阻塞等待任务完成并获取结果
result = transcription.wait(
TranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
// 打印结果
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(result.getOutput()));
} catch (Exception e) {
System.out.println("error: " + e);
}
System.exit(0);
}
}
输入文件限制
Paraformer模型 | Fun-ASR模型 | SenseVoice模型 | |
输入文件的方式 | 音频文件的URL | ||
文件数量 | 不超过100个 | ||
文件大小 | 每个URL中的文件不超过2 GB,时长为12小时以内 | 每个URL中的文件不超过2 GB,时长无限制 | |
文件格式 | aac、amr、avi、flac、flv、m4a、mkv、mov、mp3、mp4、mpeg、ogg、opus、wav、webm、wma、wmv | ||
采样率 | paraformer-v2、paraformer-v1模型对采样率无限制,其他模型支持音视频采样率为16000 Hz及以上,电话语音采样率为8000 Hz及以上 | 任意 | 任意 |
文件大小说明:如果超出限制,可尝试对文件进行预处理以降低文件尺寸。具体操作,请参见最佳实践。
音频格式说明:由于音视频文件格式及其变种众多,因此不能保证所有格式均能够被正确识别。请通过测试验证您所提供的文件能够获得正常的语音识别结果。
采样率说明:采样率是指每秒对声音信号的采样次数。更高的采样率提供更多信息,有助于提高语音识别的准确率,但过高的采样率可能引入更多无关信息,反而影响识别效果。应根据实际采样率选择合适的模型。例如,8000Hz的语音数据应直接使用支持8000Hz的模型,无需转换为16000Hz。
API参考
模型应用上架及备案
参见应用合规备案。
常见问题
1. 如何提升识别准确率?
需综合考虑影响因素并采取相应措施。
主要影响因素:
声音质量:录音设备、采样率及环境噪声影响清晰度(高质量音频是基础)
说话人特征:音调、语速、口音和方言差异(尤其少见方言或重口音)增加识别难度
语言和词汇:多语言混合、专业术语或俚语提升识别难度(热词配置可优化)
上下文理解:缺乏上下文易导致语义歧义(尤其在依赖前后文才能正确识别的语境中)
优化方法:
优化音频质量:使用高性能麦克风及推荐采样率设备;减少环境噪声与回声
适配说话人:针对显著口音/方言场景,选用支持方言的模型
配置热词:为专业术语、专有名词等设置热词(参见定制热词-Paraformer、定制热词-Gummy)
保留上下文:避免过短音频分段
2. 模型限流规则是怎样的?
录音文件识别Paraformer:
模型名称 | 提交作业接口RPS限制 | 任务查询接口RPS限制 |
paraformer-v2 | 20 | 20 |
paraformer-v1 | 10 | |
paraformer-8k-v2 | 20 | |
paraformer-8k-v1 | 10 | |
paraformer-mtl-v1 | 10 |
录音文件识别Fun-ASR:
模型名称 | 提交作业接口RPS限制 | 任务查询接口RPS限制 |
fun-asr | 10 | 20 |
fun-asr-2025-08-25 |
录音文件识别SenseVoice:
模型名称 | 提交作业接口RPS限制 | 任务查询接口RPS限制 |
sensevoice-v1 | 10 | 20 |