录音文件识别极速版支持使用者通过HTTPS POST方式上传一段短音频,并在短时间内(一般来说,30分钟的音频可以在10秒内完成识别)同步获取识别结果,满足音视频字幕、准实时质检等场景下对语音文件识别时效性要求。
计费和并发限制
功能介绍
请在编码时严格遵循以下要求,否则可能导致识别失败(识别结果为空)。
音视频格式:支持MP4、AAC、MP3、OPUS、WAV格式编码的音视频。
使用限制:支持100 MB以内且时长不超过2小时的音频文件的识别,时长超过2小时的文件请使用录音文件识别普通版。
模型类型:8000(电话)和16000(非电话)。
说明服务端根据请求参数中的采样率对不符合要求的音频自动进行采样率调整。
支持设置返回结果:支持设置是否将中文数字转为阿拉伯数字输出,支持对多声道音频只处理首个声道。
支持控制台配置项目热词、定制语言模型。
目前支持的语种和方言模型如下:
语种和方言模型无法在编码时指定,需要在智能语音交互控制台的全部项目中对相关项目执行项目功能配置操作,选择对应的模型。详情请参见管理项目。
前提条件
交互流程
客户端向服务端发送带有音频数据的HTTPS POST请求,服务端返回带有识别结果的HTTPS响应。
服务端的响应除了音频流之外,都会在返回信息的header包含本次识别任务的task_id参数,是本次请求的唯一标识。
服务地址
访问类型  | 说明  | URL  | Host  | 
外网访问  | 所有服务器均可使用外网访问URL。  | 
  | 
  | 
阿里云上海ECS内网访问  | 使用阿里云上海、北京、深圳ECS(即ECS地域为华东2(上海)、华北2(北京)、华南1(深圳)),可使用内网访问URL。 ECS的经典网络不能访问AnyTunnel,即不能在内网访问语音服务;如果希望使用AnyTunnel,需要创建专有网络在其内部访问。 说明  
  | 
  | 
  | 
以下将以使用外网访问URL的方式进行介绍。如果您使用阿里云上海ECS,并需要通过内网访问URL,则使用HTTP协议,并替换外网访问的URL和Host。
输入音频
上传二进制音频流
请求HTTPS报文示例。
POST /stream/v1/FlashRecognizer?appkey=23f5****&token=450372e4279bcc2b3c793****&format=wav&sample_rate=16000 HTT
Content-type: application/octet-stream
Content-Length: 94616
Host: nls-gateway-cn-shanghai.aliyuncs.com
[audio data]一个完整的文件识别极速版RESTful API请求需包含以下要素:HTTPS请求行、HTTPS请求头部和HTTPS请求体。
HTTPS请求行
HTTPS请求行指定了URL和请求参数,由URL和请求参数组成的完整请求链接如下:
https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer?appkey=Yu1******uncS&format=wav&sample_rate=16000&vocabulary_id=a17******d6b&token=1234*****URL
协议
URL
方法
HTTP/1.1
nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer
POST
请求参数
参数
类型
是否必选
描述
appkey
String
是
应用Appkey。
format
String
是
音频编码格式。支持格式:MP4、AAC、MP3、OPUS、WAV。
token
String
是
鉴权Token。
sample_rate
Integer
否
表示语音识别模型的采样率,上传的音频如果不符合其取值会被自动升/降采样率至8000或16000。取值:16000(非电话)/8000(电话)。默认:16000。
vocabulary_id
String
否
添加热词表ID。默认:不添加。
customization_id
String
否
添加自学习模型ID。默认:不添加。
enable_inverse_text_normalization
Boolean
否
ITN(逆文本inverse text normalization)中文数字转换阿拉伯数字。设置为True时,中文数字将转为阿拉伯数字输出,默认值:False。
enable_word_level_result
Boolean
否
是否返回词级别信息。取值:true或false。默认:false(不开启)。
enable_timestamp_alignment
Boolean
否
是否启用时间戳校准功能,取值:true或false,默认:false(不开启)。
first_channel_only
Boolean
否
是否只识别首个声道,取值:true/false。(如果录音识别结果重复,您可以开启此参数。)
默认为空:8k处理双声道,16k处理单声道。
false:8k处理双声道,16k处理双声道。
true:8k处理单声道,16k处理单声道。
说明如果为多声道将会叠加计费。例如,双声道为双倍计费。
speech_noise_threshold
Float
否
噪音参数阈值,取值范围:[-1, 1]。取值说明如下:
取值越趋于-1,噪音被判定为语音的概率越大。
取值越趋于+1,语音被判定为噪音的概率越大。
重要该参数属高级参数,请慎重调整并进行重点测试。
special_word_filter
String(结构为JSON格式)
否
敏感词过滤功能,支持开启或关闭,支持自定义敏感词。该参数可实现:
不处理(默认,即展示原文)、过滤、替换为*。
具体调用说明请见下文的自定义过滤词调用示例。
说明开启但未配置敏感词,则会过滤默认词表:敏感词表。
sentence_max_length
Integer
否
每句最多展示字数,取值范围:[4,50]。默认不启用该功能。启用后如不填写字数,则按照长句断句。该参数可用于字幕生成场景,控制单行字幕最大字数。
自定义过滤词调用示例如下:
// 以实时转写为例, JSONObject root = new JSONObject(); root.put("system_reserved_filter", true); // 将以下词语替换成空 JSONObject root1 = new JSONObject(); JSONArray array1 = new JSONArray(); array1.add("开始"); array1.add("发生"); root1.put("word_list", array1); // 将以下词语替换成* JSONObject root2 = new JSONObject(); JSONArray array2 = new JSONArray(); array2.add("测试"); root2.put("word_list", array2); // 可以全部设置,也可以部分设置 root.put("filter_with_empty", root1); root.put("filter_with_signed", root2); transcriber.addCustomedParam("special_word_filter", root);
HTTPS请求头部
HTTPS请求头部由“关键字-值”对组成,每行一对,关键字和值用英文冒号“:”分隔,设置内容如下:
名称
类型
是否必选
描述
Content-type
String
是
取值“application/octet-stream”,表明HTTPS请求体的数据为二进制流。
Content-Length
long
是
HTTPS请求体中请求数据的长度,即音频文件的长度。
Host
String
是
取值“nls-gateway-cn-shanghai.aliyuncs.com”,为HTTPS请求的服务器域名。
HTTPS请求体
HTTPS请求体传入的是二进制音频数据,因此在HTTPS请求头部中的
Content-Type必须设置为application/octet-stream。
使用音频文件链接
如果希望使用非本地音频文件直接进行识别,可以使用音频链接的方式请求,此种调用方式无需上传音频文件。请求HTTPS报文示例如下:
POST /stream/v1/FlashRecognizer?appkey=23f5****&token=450372e4279bcc2b3c793****&format=wav&sample_rate=16000&audio_address=https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wa
HTTP Content-type: application/text 
Host: nls-gateway-cn-shanghai.aliyuncs.com一个完整的文件识别极速版RESTful API请求需包含以下要素:HTTPS请求行和HTTPS请求头部。
HTTPS请求行
HTTPS请求行指定了URL和请求参数,由URL和请求参数组成的完整请求链接如下:
https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer?appkey=Yu1******uncS&format=wav&sample_rate=16000&vocabulary_id=a17******d6b&token=1234*****URL
协议
URL
方法
HTTP/1.1
nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer
POST
请求参数
参数
类型
是否必选
描述
appkey
String
是
应用Appkey。
format
String
是
音频编码格式。支持格式:MP4、WAV、OPUS、AAC、MP3。
token
String
是
鉴权Token。
sample_rate
Integer
否
表示语音识别模型的采样率,上传的音频如果不符合其取值会被自动升/降采样率至8000或16000。取值:16000(非电话)或8000(电话)。默认:16000。
vocabulary_id
String
否
添加热词表ID。默认:不添加。
customization_id
String
否
添加自学习模型ID。默认:不添加。
enable_inverse_text_normalization
Boolean
否
ITN(逆文本inverse text normalization)中文数字转换阿拉伯数字。设置为True时,中文数字将转为阿拉伯数字输出,默认值:False。
enable_word_level_result
Boolean
否
是否返回词级别信息。取值:true或false。默认:false(不开启)。
enable_timestamp_alignment
Boolean
否
是否启用时间戳校准功能,取值:true或false,默认:false(不开启)。
first_channel_only
Boolean
否
是否只识别首个声道,取值:true/false。(如果录音识别结果重复,您可以开启此参数。)
默认为空:8k处理双声道,16k处理单声道。
false:8k处理双声道,16k处理双声道。
true:8k处理单声道,16k处理单声道。
说明如果为多声道将会叠加计费。例如,双声道为双倍计费。
speech_noise_threshold
Float
否
噪音参数阈值,取值范围:[-1, 1]。取值说明如下:
取值越趋于-1,噪音被判定为语音的概率越大。
取值越趋于+1,语音被判定为噪音的概率越大。
重要该参数属高级参数,请慎重调整并进行重点测试。
audio_address
String
是
使用音频文件链接时必填,存放录音文件的地址,推荐使用阿里云OSS。
HTTPS请求头部
HTTPS请求头部由“关键字-值”对组成,每行一对,关键字和值用英文冒号“:”分隔,设置内容如下:
名称
类型
是否必选
描述
Content-type
String
是
取值“application/text”。
Host
String
是
取值“nls-gateway-cn-shanghai.aliyuncs.com”,为HTTPS请求的服务器域名。
响应结果
发送上传音频的HTTPS请求后,会收到服务端的响应,识别结果以JSON字符串的形式保存在响应结果中。
成功响应
{ "task_id":"a819f959441b49****", "status":20000000, "message":"SUCCESS", "flash_result":{ "duration":22, "sentences":[ { "text":"喂,", "words":[ { "text":"喂", "begin_time":"1010", "end_time":"1520", "punc":"," } ], "begin_time":1010, "end_time":1520, "channel_id":1 }, { "text":"哎,", "words":[ { "text":"哎", "begin_time":"3540", "end_time":"3570", "punc":"," } ], "begin_time":3540, "end_time":3570, "channel_id":1 }, { "text":"那五点五十现在是多少点啊,", "words":[ { "text":"那", "begin_time":"8810", "end_time":"8840", "punc":"" }, { "text":"五点", "begin_time":"12750", "end_time":"13200", "punc":"" }, { "text":"五十", "begin_time":"13200", "end_time":"13890", "punc":"" }, { "text":"现在", "begin_time":"14330", "end_time":"14600", "punc":"" }, { "text":"是", "begin_time":"14600", "end_time":"14720", "punc":"" }, { "text":"多少", "begin_time":"14720", "end_time":"14960", "punc":"" }, { "text":"点", "begin_time":"19570", "end_time":"21220", "punc":"" }, { "text":"啊", "begin_time":"21220", "end_time":"22330", "punc":"" } ], "begin_time":8810, "end_time":22330, "channel_id":1 } ] } }响应字段说明如下:
参数
类型
描述
task_id
String
32位任务ID。请您记录该值,以便排查错误。
status
Integer
服务状态码。
message
String
服务状态描述。
flash_result对象参数说明:
参数
类型
描述
duration
Integer
音频时长,单位:毫秒。
latency
Integer
服务端处理时长,单位:毫秒。
sentences.text
String
句子级别的识别结果。
sentences.begin_time
Integer
句子的开始时间,单位:毫秒。
sentences.end_time
Integer
句子的结束时间,单位:毫秒。
sentences.channel_id
Integer
多个声道的音频文件会区分返回识别结果,声道ID从0计数。
sentences.words.text
String
当前句子包含的词信息。
sentences.words.punc
String
当前词尾的标点信息,没有标点则为空。
sentences.words.begin_time
Integer
当前词开始时间,单位:毫秒。
sentences.words.end_time
Integer
当前词结束时间,单位:毫秒。
失败响应
以鉴权Token无效为例:
{ "task_id": "8bae3613dfc54ebfa811a17d8a7a****", "result": "", "status": 40000001, "message": "Gateway:ACCESS_DENIED:The token 'c0c1e860f3*******de8091c68a' is invalid!" }
服务状态码
通用错误码
状态码  | 状态消息  | 原因  | 解决方案  | 
40000000  | 默认的客户端错误码,对应了多个错误消息。  | 用户使用了不合理的参数或者调用逻辑。  | 请参考官网文档示例代码进行对比测试验证。  | 
40000001  | The token 'xxx' has expired; The token 'xxx' is invalid  | 用户使用了不合理的参数或者调用逻辑。通用客户端错误码,通常是涉及Token相关的不正确使用,例如Token过期或者非法。  | 请参考官网文档示例代码进行对比测试验证。  | 
40000002  | Gateway:MESSAGE_INVALID:Can't process message in state'FAILED'!  | 无效或者错误的报文消息。  | 请参考官网文档示例代码进行对比测试验证。  | 
40000003  | PARAMETER_INVALID; Failed to decode url params  | 用户传递的参数有误,一般常见于RESTful接口调用。  | 请参考官网文档示例代码进行对比测试验证。  | 
40000005  | Gateway:TOO_MANY_REQUESTS:Too many requests!  | 并发请求过多。  | 如果是试用版调用,建议您升级为商用版本以增大并发。 如果已是商用版,可购买并发资源包,扩充您的并发额度。  | 
40000009  | Invalid wav header!  | 错误的消息头。  | 如果您发送的是WAV语音文件,且设置  | 
40000009  | Too large wav header!  | 传输的语音WAV头不合法。  | 建议使用PCM、OPUS等格式发送音频流,如果是WAV,建议关注语音文件的WAV头信息是否为正确的数据长度大小。  | 
40000010  | Gateway:FREE_TRIAL_EXPIRED:The free trial has expired!  | 试用期已结束,并且未开通商用版、或账号欠费。  | 请登录控制台确认服务开通状态以及账户余额。  | 
40010001  | Gateway:NAMESPACE_NOT_FOUND:RESTful url path illegal  | 不支持的接口或参数。  | 请检查调用时传递的参数内容是否和官网文档要求的一致,并结合错误信息对比排查,设置为正确的参数。 比如您是否通过curl命令执行RESTful接口请求, 拼接的URL是否合法。  | 
40010003  | Gateway:DIRECTIVE_INVALID:[xxx]  | 客户端侧通用错误码。  | 表示客户端传递了不正确的参数或指令,在不同的接口上有对应的详细报错信息,请参考对应文档进行正确设置。  | 
40010004  | Gateway:CLIENT_DISCONNECT:Client disconnected before task finished!  | 在请求处理完成前客户端主动结束。  | 无,或者请在服务端响应完成后再关闭链接。  | 
40010005  | Gateway:TASK_STATE_ERROR:Got stop directive while task is stopping!  | 客户端发送了当前不支持的消息指令。  | 请参考官网文档示例代码进行对比测试验证。  | 
40020105  | Meta:APPKEY_NOT_EXIST:Appkey not exist!  | 使用了不存在的Appkey。  | 请确认是否使用了不存在的Appkey,Appkey可以通过登录控制台后查看项目配置。  | 
40020106  | Meta:APPKEY_UID_MISMATCH:Appkey and user mismatch!  | 调用时传递的Appkey和Token并非同一个账号UID所创建,导致不匹配。  | 请检查是否存在两个账号混用的情况,避免使用账号A名下的Appkey和账号B名下生成的Token搭配使用。  | 
403  | Forbidden  | 使用的Token无效,例如Token不存在或者已过期。  | 请设置正确的Token。Token存在有效期限制,请及时在过期前获取新的Token。  | 
41000003  | MetaInfo doesn't have end point info  | 无法获取该Appkey的路由信息。  | 请检查是否存在两个账号混用的情况,避免使用账号A名下的Appkey和账号B名下生成的Token搭配使用。  | 
41010101  | UNSUPPORTED_SAMPLE_RATE  | 不支持的采样率格式。  | 当前实时语音识别只支持8000 Hz和16000 Hz两种采样率格式的音频。  | 
41040201  | Realtime:GET_CLIENT_DATA_TIMEOUT:Client data does not send continuously!  | 获取客户端发送的数据超时失败。  | 客户端在调用实时语音识别时请保持实时速率发送,发送完成后及时关闭链接。  | 
50000000  | GRPC_ERROR:Grpc error!  | 受机器负载、网络等因素导致的异常,通常为偶发出现。  | 一般重试调用即可恢复。  | 
50000001  | GRPC_ERROR:Grpc error!  | 受机器负载、网络等因素导致的异常,通常为偶发出现。  | 一般重试调用即可恢复。  | 
52010001  | GRPC_ERROR:Grpc error!  | 受机器负载、网络等因素导致的异常,通常为偶发出现。  | 一般重试调用即可恢复。  | 
录音文件识别极速版错误码
状态码  | 状态消息  | 原因  | 解决方案  | 
40000004  | Gateway:IDLE_TIMEOUT:Websocket session is idle for too long time  | 提交任务后,超过50s没有返回任务结果,服务端会返回此错误信息。  | 如果任务返回此错误码,可以重试提交此任务。建议一个任务返回此错误码最多重试2次。  | 
40000005  | -  | 请求数量过多。  | 检查是否超过了并发连接数或者每秒钟请求数。  | 
40270001  | -  | 不支持的音频格式。  | 请求音频格式不在支持列表。  | 
40270002  | NO_VALID_AUDIO_ERROR  | 无效的音频。  | 从音频中没有识别出有效文本。  | 
40270003  | -  | 音频解码错误。  | 按请求格式对音频解码时遇到错误。  | 
40270004  | -  | 无有效音频流。  | 多声道的音频中未抽取到有效音频流。  | 
40270006  | -  | 文件下载失败。  | 检查文件链接是否有效。  | 
快速测试
音频示例WAV文件,使用通用模型。若使用其他音频文件,请填入相应的编码格式和采样率,并在管控台设置对应的模型。
使用如下cURL命令行进行极速版识别的RESTful API测试。
curl -X POST 'https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer?appkey=${appkey}&token=${token}&format=wav&sample_rate=16000' --data-binary @${audio_file}举例如下:
curl -X POST 'https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer?appkey=tt43P2u****&token=4a036531cfdd****&format=wav&sample_rate=16000' --data-binary @./nls-sample-16k.wav
Java示例
依赖文件如下:
<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>3.9.1</version>
</dependency>
<!-- http://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.83</version>
</dependency>发送请求与响应:
import java.net.URLEncoder;
import java.io.File;
import java.util.HashMap;
public class SpeechFlashRecognizerDemo {
    private String appkey;
    public SpeechFlashRecognizerDemo(String appkey) {
        this.appkey = appkey;
    }
    public void process(String fileName, String token,String format, int sampleRate) {
        /**
        * 设置HTTPS REST POST请求
        * 1.使用http协议
        * 2.语音识别服务域名:nls-gateway-cn-shanghai.aliyuncs.com
        * 3.语音识别接口请求路径:/stream/v1/FlashRecognizer
        * 4.设置必须请求参数:appkey、token、format、sample_rate
        */
        String url = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer";
        String request = url;
        request = request + "?appkey=" + appkey;
        request = request + "&token=" + token;
        request = request + "&format=" + format;
        request = request + "&sample_rate=" + sampleRate;
        
        System.out.println("Request: " + request);
        /**
        * 设置HTTPS头部字段
        *
        * 1.Content-Type:application/octet-stream
        */
        HashMap<String, String> headers = new HashMap<String, String>();
        /**
        * 发送HTTPS POST请求,返回服务端的响应。
        */
        long start = System.currentTimeMillis();
        String response;
        if (new File(fileName).isFile()){
            headers.put("Content-Type", "application/octet-stream");
            response = HttpUtil.sendPostFile(request, headers, fileName);
        }else {
            headers.put("Content-Type", "application/text");
            response = HttpUtil.sendPostLink(request, headers, fileName);
        }
        System.out.println("latency = " + (System.currentTimeMillis() - start) + " ms");
        if (response != null) {
            System.out.println("Response: " + response);
            
        }
        else {
            System.err.println("识别失败!");
        }
        
    }
    public static void main(String[] args) {
        
        if (args.length < 2) {
            System.err.println("SpeechRecognizerRESTfulDemo need params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        
        
        
        SpeechFlashRecognizerDemo demo = new SpeechFlashRecognizerDemo(appkey);
        //String fileName = SpeechRecognizerRestfulDemo.class.getClassLoader().getResource("./nls-sample-16k.wav").getPath();
        // 重要:此处用一个本地文件来模拟发送实时流数据,实际使用时,您可以从某处实时采集或接收语音流并发送到ASR服务端。
        String fileName = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
        fileName = URLEncoder.encode(fileName, "UTF-8"); 
        String format = "wav";
        int sampleRate = 16000;
        
        demo.process(fileName,token, format, sampleRate);
        System.exit(-1);
    }
}其中,HttpUtils类如下:
import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class HttpUtil {
    
    private static String getResponseWithTimeout(Request q) {
        String ret = null;
        
        OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
        OkHttpClient client = httpBuilder.connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .build();
        
        try {
            Response s = client.newCall(q).execute();
            ret = s.body().string();
            s.close();
        } catch (SocketTimeoutException e) {
            ret = null;
            System.err.println("get result timeout");
        } catch (IOException e) {
            System.err.println("get result error " + e.getMessage());
        }
        
        return ret;
    }
    
    public static String sendPostFile(String url, HashMap<String, String> headers, String fileName) {
        RequestBody body;
        
        File file = new File(fileName);
        if (!file.isFile()) {
            System.err.println("The filePath is not a file: " + fileName);
            return null;
        } else {
            body = RequestBody.create(MediaType.parse("application/octet-stream"), file);
        }
        
        Headers.Builder hb = new Headers.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                hb.add(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = new Request.Builder()
            .url(url)
            .headers(hb.build())
            .post(body)
            .build();
        
        return getResponseWithTimeout(request);
    }
    
    public static String sendPostData(String url, HashMap<String, String> headers, byte[] data) {
        RequestBody body;
        
        if (data.length == 0) {
            System.err.println("The send data is empty.");
            return null;
        } else {
            body = RequestBody.create(MediaType.parse("application/octet-stream"), data);
        }
        
        Headers.Builder hb = new Headers.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                hb.add(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = new Request.Builder()
            .url(url)
            .headers(hb.build())
            .post(body)
            .build();
        
        return getResponseWithTimeout(request);
    }
    
    public static String sendPostLink(String url, HashMap<String, String> headers, String link){
        RequestBody body;
        
        if (link.isEmpty()) {
            System.err.println("The send link is empty.");
            return null;
        } else {
            url=url+"&audio_address="+link;
        }
        
        Headers.Builder hb = new Headers.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                hb.add(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = new Request.Builder()
            .url(url)
            .headers(hb.build())
            .build();
        
        return getResponseWithTimeout(request);
    }
}C++示例
C++示例使用第三方函数库curl处理HTTPS请求和响应,下载curl库和示例文件。
目录说明如下:
文件/文件夹  | 说明  | 
CMakeLists.txt  | 示例工程的CMakeList文件。  | 
demo  | 其中的restfulFlashRecognizerDemo.cpp是极速版RESTful API示例。  | 
include  | 其中curl文件夹是curl库头文件目录。  | 
lib  | 包含curl动态库,版本为curl-7.60。根据平台不同选如下版本: 
  | 
readme.txt  | 说明。  | 
release.log  | 更新记录。  | 
version  | 版本号。  | 
build.sh  | 示例编译脚本。  | 
编译运行操作步骤:
假设示例文件已解压至path/to路径下,在Linux终端依次执行如下命令编译运行程序。
支持Cmake:
确认本地系统已安装Cmake 2.4及以上版本。
切换目录:
cd path/to/sdk/lib。解压缩文件:
tar -zxvpf linux.tar.gz。切换目录:
cd path/to/sdk。执行编译脚本:
./build.sh。切换目录:
cd path/to/sdk/demo。执行示例程序:
./restfulFlashRecognizerDemo <your-token> <your-appkey>。
不支持Cmake:
切换目录:
cd path/to/sdk/lib。解压缩文件:
tar -zxvpf linux.tar.gz。切换目录:
cd path/to/sdk/demo。使用g++编译命令编译示例程序:
g++ -o restfulFlashRecognizerDemo restfulFlashRecognizerDemo.cpp -I path/to/sdk/include -L path/to/sdk/lib/linux -lssl -lcrypto -lcurl -D_GLIBCXX_USE_CXX11_ABI=0。指定库路径:
export LD_LIBRARY_PATH=path/to/sdk/lib/linux/。执行示例程序:
./restfulFlashRecognizerDemo <your-token> <your-appkey>。
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "curl/curl.h"
using namespace std;
#ifdef _WIN32
string UTF8ToGBK(const string& strUTF8) {
    int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
    unsigned short * wszGBK = new unsigned short[len + 1];
    memset(wszGBK, 0, len * 2 + 2);
    MultiByteToWideChar(CP_UTF8, 0, (char*)strUTF8.c_str(), -1, (wchar_t*)wszGBK, len);
    len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)wszGBK, -1, NULL, 0, NULL, NULL);
    char *szGBK = new char[len + 1];
    memset(szGBK, 0, len + 1);
    WideCharToMultiByte(CP_ACP, 0, (wchar_t*)wszGBK, -1, szGBK, len, NULL, NULL);
    string strTemp(szGBK);
    delete[] szGBK;
    delete[] wszGBK;
    return strTemp;
}
#endif
/**
 * RESTful API HTTPS请求的响应回调函数
 * 识别结果为JSON格式的字符串
 */
size_t responseCallback(void* ptr, size_t size, size_t nmemb, void* userData) {
    string* srResult = (string*)userData;
    size_t len = size * nmemb;
    char *pBuf = (char*)ptr;
    string response = string(pBuf, pBuf + len);
#ifdef _WIN32
    response = UTF8ToGBK(response);
#endif
    *srResult += response;
    cout << "current result: " << response << endl;
    cout << "total result: " << *srResult << endl;
    return len;
}
int sendAsrRequest(const char* request, const char* token, const char* fileName, string* srResult) {
    CURL* curl = NULL;
    CURLcode res;
    /**
    * 读取音频文件
    */
    ifstream fs;
    fs.open(fileName, ios::out | ios::binary);
    if (!fs.is_open()) {
        cerr << "The audio file is not exist!" << endl; 
        return -1;
    }
    stringstream buffer;
    buffer << fs.rdbuf();
    string audioData(buffer.str());
    curl = curl_easy_init();
    if (curl == NULL) {
        return -1;
    }
    /**
    * 设置HTTPS请求行
    */
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_URL, request);
    /**
    * 设置HTTPS请求头部
    */
    struct curl_slist* headers = NULL;
    // Content-Type
    headers = curl_slist_append(headers, "Content-Type:application/octet-stream");
    // Content-Length
    string content_Length = "Content-Length:";
    ostringstream oss;
    oss << content_Length << audioData.length();
    content_Length = oss.str();
    headers = curl_slist_append(headers, content_Length.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    /**
    * 设置HTTPS请求数据
    */
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audioData.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, audioData.length());
    /**
    * 设置HTTPS请求的响应回调函数
    */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, srResult);
    /**
    * 发送HTTPS请求
    */
    res = curl_easy_perform(curl);
    // 释放资源
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    if (res != CURLE_OK) {
        cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
        return -1;
    }
    return 0;
}
int process(const char* request, const char* token, const char* fileName) {
    // 全局只初始化一次
    curl_global_init(CURL_GLOBAL_ALL);
    string srResult = "";
    int ret = sendAsrRequest(request, token, fileName, &srResult);
    curl_global_cleanup();
    return ret;
}
int main(int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "params is not valid. Usage: ./demo your_token your_appkey" << endl;
        return -1;
    }
    string token = argv[1];
    string appKey = argv[2];
    string url = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer";
    string format = "wav";
    int sampleRate = 16000;
    string fileName = "nls-sample-16k.wav";
    /**
    * 设置RESTful请求参数
    */
    ostringstream oss;
    oss << url;
    oss << "?appkey=" << appKey;
    oss << "&token=" << token;
    oss << "&format=" << format;
    oss << "&sample_rate=" << sampleRate;
    string request = oss.str();
    cout << "request: " << request << endl;
    process(request.c_str(), token.c_str(), fileName.c_str());
    return 0;
}Python示例
Python 2.x请使用httplib模块;Python 3.x请使用http.client模块。
采用RFC 3986规范进行urlencode编码,Python 2.x请使用urllib模块的urllib.quote,Python 3.x请使用urllib.parse模块的urllib.parse.quote_plus。
如果使用内网访问URL,请使用HTTP协议,需要替换如下函数,即将
HTTPSConnection修改为HTTPConnection:# Python 2.x 请使用httplib # conn = httplib.HTTPConnection(host) # Python 3.x 请使用http.client conn = http.client.HTTPConnection(host)
# -*- coding: UTF-8 -*-
# Python 2.x引入httplib模块
# import httplib
# Python 3.x引入http.client模块
import http.client
import json
def process(request,  audioFile) :
    # 读取音频文件
    with open(audioFile, mode = 'rb') as f:
        audioContent = f.read()
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    # 设置HTTP请求头部
    httpHeaders = {
        'Content-Length': len(audioContent)
        }
    # Python 2.x使用httplib
    # conn = httplib.HTTPSConnection(host)
    # Python 3.x使用http.client
    conn = http.client.HTTPSConnection(host)
    conn.request(method='POST', url=request, body=audioContent, headers=httpHeaders)
    response = conn.getresponse()
    print('Response status and response reason:')
    print(response.status ,response.reason)
    body = response.read()
    try:
        print('Recognize response is:')
        body = json.loads(body)
        print(body)
        status = body['status']
        if status == 20000000 :
            result = body['result']
            print('Recognize result: ' + result)
        else :
            print('Recognizer failed!')
    except ValueError:
        print('The response is not json format string')
    conn.close()
appKey = '您的appkey'
token = '您的token'
# 服务请求地址
url = 'https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer'
# 音频文件,下载地址:https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav
audioFile = 'nls-sample-16k.wav'
format = 'wav'
sampleRate = 16000
print(type(sampleRate))
enablePunctuationPrediction  = True
enableInverseTextNormalization = True
enableVoiceDetection  = False
# 设置RESTful请求参数
request = url + '?appkey=' + appKey
request = request + '&token=' + token
request = request + '&format=' + format
request = request + '&sample_rate=' + str(sampleRate)
print('Request: ' + request)
process(request, audioFile)PHP示例
PHP示例中使用了cURL函数,要求PHP版本在4.0.2以上,并且确保已安装cURL扩展。
<?php
function process($token, $request, $audioFile)
 {
/**
* 读取音频文件
*/
$audioContent = file_get_contents($audioFile);
if ($audioContent == FALSE) {
print "The audio file is not exist!\n";
return;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
/**
* 设置HTTP请求行
*/
curl_setopt($curl, CURLOPT_URL, $request);
curl_setopt($curl, CURLOPT_POST,TRUE);
/**
* 设置HTTP请求头部
*/
$contentType = "application/octet-stream";
$contentLength = strlen($audioContent);
$headers = array(
// "X-NLS-Token:" . $token,
"Content-type:" . $contentType,
"Content-Length:" . strval($contentLength)
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
/**
* 设置HTTP请求数据
*/
curl_setopt($curl, CURLOPT_POSTFIELDS, $audioContent);
curl_setopt($curl, CURLOPT_NOBODY, FALSE);
/**
* 发送HTTP请求
*/
$returnData = curl_exec($curl);
curl_close($curl);
if ($returnData == FALSE) {
print "curl_exec failed!\n";
return;
}
print $returnData . "\n";
$resultArr = json_decode($returnData, true);
$status = $resultArr["status"];
if ($status == 20000000) {
$result = $resultArr["result"];
print "The audio file recognized result: " . $result . "\n";
}
else {
print "The audio file recognized failed.\n";
}
}
$appkey = "您的appkey";
$token = "您的token";
$url = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/FlashRecognizer";
//$audioFile = "/path/to/nls-sample-16k.wav";
$audioFile = "./nls-sample-16k.wav";
$format = "wav";
$sampleRate = 16000;
/**
* 设置RESTful请求参数
*/
$request = $url;
$request = $request . "?appkey=" . $appkey;
$request = $request . "&token=" . $token;
$request = $request . "&format=" . $format;
$request = $request . "&sample_rate=" . strval($sampleRate);
print "Request: " . $request . "\n";
process($token, $request, $audioFile);
?>