C# SDK
本文介绍如何使用阿里云智能语音服务提供的C# SDK,包括SDK的安装方法及SDK代码示例。
SDK下载
当前最新版本:3.1.14,该版本基于C++ SDK API 3.1.x。发布日期:2022年11月09日。
使用SDK前,请先阅读接口说明,详情请参见接口说明。
可通过以下两种方法获取SDK。
方法一:从GitHub获取最新源码,详细编译和运行方式可见下文,或查看源码中的readme.md。
git clone --depth 1 https://github.com/aliyun/alibabacloud-nls-cpp-sdk
方法二:直接从下文表中选取需要的SDK包进行下载。其中SDK源码包为SDK原始代码,需要通过下文编译方法生成集成所需的库文件。其他对应平台的SDK包内含相关库文件、头文件,无需编译。
最新SDK包 | 平台 | MD5 |
SDK源码 | f5f951190fbc10b39c41239f0483758e | |
Windows | 7a9eb5265d6e0a3462a0e09e3645bacb |
其中:
alibabacloud-nls-cpp-sdk<version>-master_<github commit id>.zip为SDK源码包。
NlsCsharpSdk_Windows_<版本号>_<github commit id>.zip为Windows平台下开发需要的SDK包,详见内部readme.md。
Windows平台C#编译运行
推荐直接使用已经编译好的库NlsCsharpSdk_Windows_<version>_<github commit id>.zip进行集成。若有编译需求,请下载alibabacloud-nls-cpp-sdk<version>-master_<github commit id>.zip并解压到本地,或从GitHub获取最新代码,然后参考其中readme.md的编译步骤。
关键接口
using nlsCsharpSdk;
基础接口
NlsClient:语音处理客户端,利用该客户端可以进行一句话识别、实时语音识别和语音合成的语音处理任务。该客户端为线程安全,建议全局仅创建一个实例。
接口名
功能描述
SetLogConfig
设置日志文件与存储路径。
StartWorkThread
启动工作线程数,默认1即启动一个线程,若-1则启动CPU核数的线程数。在高并发的情况下建议选择-1。这一接口有初始化NlsClient的作用。
ReleaseInstance
销毁NlsClient对象实例,即释放NLS SDK。
GetVersion
获取SDK版本号。
CreateRecognizerRequest
创建一句话识别对象,线程安全,支持高并发请求。
ReleaseRecognizerRequest
销毁一句话识别对象,需要在当前请求的closed事件后调用。
NlsToken:创建Token对象,用于申请获取TokenId。申请新Token时需要先获取有效时间戳,若超过有效时间则再申请。若在有效时间内多次申请Token会导致TokenId错误而无法使用。
接口名
功能描述
SetAccessKeyId
设置阿里云账号AccessKey ID。
SetKeySecret
设置阿里云账号AccessKey Secret。
ApplyNlsToken
申请获取TokenId。
GetToken
获取TokenId
GetExpireTime
获取Token有效期时间戳(秒)。
NlsEvent:事件对象,您可以从中获取Request状态码、云端返回结果、失败信息等。
接口名
功能描述
statusCode
获取状态码,正常情况为0或者20000000,失败时对应失败的错误码。
taskId
获取任务的TaskId。
msg
获取云端返回的response结果。
result
获取云端返回的识别结果。
识别接口
SpeechRecognizerRequest:一句话识别请求对象,用于短语音识别。
接口名
功能描述
SetOnTaskFailed
设置错误回调函数。
SetOnRecognitionStarted
设置一句话识别开始回调函数。
SetOnRecognitionResultChanged
设置一句话识别中间结果回调函数。
SetOnRecognitionCompleted
设置服务端结束服务回调函数。
SetOnChannelClosed
设置通道关闭回调函数。
SetAppKey
设置Appkey。
SetToken
口令认证。所有的请求都必须通过SetToken方法认证通过,才可以使用。
SetUrl
设置服务URL地址。
SetIntermediateResult
设置是否返回中间识别结果。
SetPunctuationPrediction
设置是否在后处理中添加标点。
SetInverseTextNormalization
设置是否在后处理中执行数字转换。
SetEnableVoiceDetection
设置是否启动自定义静音检测。
SetMaxStartSilence
超出后服务端将会发送RecognitionCompleted事件,结束本次识别。
SetMaxEndSilence
超出后服务端将会发送RecognitionCompleted事件,结束本次识别。
SetFormat
设置音频数据编码格式。
SetSampleRate
音频采样率设置。
SetCustomizationId
设置定制模型。
SetVocabularyId
设置泛热词。
SetTimeout
设置Socket接收超时时间。
SetOutputFormat
设置输出文本的编码格式。
SetPayloadParam
参数设置。
SetContextParam
设置用户自定义参数。
AppendHttpHeaderParam
设置用户自定义ws阶段http header参数。
Start
启动SpeechRecognizerRequest。
Stop
会与服务端确认关闭,正常停止链接操作。
Cancel
不会与服务端确认关闭,直接关闭链接。
SendAudio
发送语音数据。
错误码
错误码 | 错误描述 | 解决方案 |
10000001 |
| 建议重试。 |
10000002 | OpenSSL官方错误描述 | 根据描述提示处理后,重试。 |
10000003 | 系统错误描述 | 根据系统错误描述提示处理。 |
10000004 |
| 检查是否设置云端URL地址。 |
10000005 |
| 检查是否正确设置云端URL地址。 |
10000006 |
| 检查是否正确设置了语音功能模式。 |
10000007 |
| 服务端发送错误响应内容,请提供task_id,并反馈给阿里云。 |
10000008 |
| 服务端发送错误WebSocket类型,请您加入钉钉群23050005920并提供task_id,咨询产品技术支持。 |
10000009 |
| 与云端连接失败,请检查网络后,重试。 |
HTTP协议官方状态码 |
| 根据HTTP协议官方描述提示处理。 |
系统错误码 |
| 根据系统错误描述提示处理。 |
系统错误码 |
| 根据系统错误描述提示处理。 |
10000010 |
| 内存不足,请检查本地机器内存。 |
10000011 |
| 接口调用顺序错误(接收到Failed/complete事件时,SDK内部会关闭连接。此时再调用send方法会上报错误)。 |
10000012 |
| 参数错误。请检查参数设置是否正确。 |
10000013 |
| 发送错误。请检查发送参数是否正确。 |
10000014 |
| 调用start方法超时错误。请调用stop方法释放资源,重新开始识别流程。 |
10000015 |
| 调用connect方法失败。请调用stop方法释放资源,重新开始识别流程。 |
服务端响应状态码
关于服务状态码,请参见服务状态码。
代码示例
示例中使用的音频文件为16000Hz采样率,管控台设置的模型为通用模型。如果使用其他音频,请设置为支持该音频场景的模型。关于模型设置,请参见管理项目。
示例中使用了SDK内置的默认一句话识别服务的外网访问服务URL,如果您使用阿里云上海ECS且需要使用内网访问URL,则在创建SpeechRecognizerRequest的对象中设置内网访问的URL。
SpeechRecognizerRequest srPtr; srPtr.SetUrl(srPtr, "ws://nls-gateway.cn-shanghai-internal.aliyuncs.com/ws/v1")
以下为简要示例,完整示例请参见SDK压缩包中demo目录的nlsCsharpSdkDemo.cs文件。
using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using nlsCsharpSdk;
namespace nlsCsharpSdkDemo
{
public partial class nlsCsharpSdkDemo : Form
{
private NlsClient nlsClient;
private SpeechRecognizerRequest srPtr;
private NlsToken tokenPtr;
private UInt64 expireTime;
private string appKey;
private string akId;
private string akSecret;
private string token;
private string url;
static bool running;
static string cur_nls_result;
static bool sr_send_audio_flag = false;
static bool sr_audio_loop_flag = false;
static Thread sr_send_audio;
static string cur_sr_result;
static string cur_sr_completed;
static string cur_sr_closed;
private void FlushLab()
{
while (running)
{
if (cur_nls_result != null && cur_nls_result.Length > 0)
{
nlsResult.Text = cur_nls_result;
}
if (cur_sr_result != null && cur_sr_result.Length > 0)
{
srResult.Text = cur_sr_result;
}
if (cur_sr_completed != null && cur_sr_completed.Length > 0)
{
srCompleted.Text = cur_sr_completed;
}
if (cur_sr_closed != null && cur_sr_closed.Length > 0)
{
srClosed.Text = cur_sr_closed;
}
Thread.Sleep(200);
}
}
private void SRAudioLab()
{
string file_name = System.Environment.CurrentDirectory + @"\audio_files\test3.wav";
System.Diagnostics.Debug.WriteLine("sr audio file_name = {0}", file_name);
FileStream fs = new FileStream(file_name, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
while (sr_audio_loop_flag)
{
if (sr_send_audio_flag)
{
byte[] byData = br.ReadBytes((int)640);
if (byData.Length > 0)
{
// 音频数据以PCM格式,byData.Length字节进行推送。
srPtr.SendAudio(srPtr, byData, (UInt64)byData.Length, EncoderType.ENCODER_PCM);
}
else
{
br.Close();
fs.Dispose();
fs = new FileStream(file_name, FileMode.Open, FileAccess.Read);
br = new BinaryReader(fs);
}
}
Thread.Sleep(20);
}
br.Close();
fs.Dispose();
}
public nlsCsharpSdkDemo()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
nlsClient = new NlsClient();
}
private void button1_Click(object sender, EventArgs e)
{
// 开启日志系统,以Debug级别将名字为nlsLog.log的日志以单个400MB 10个日志文件循环的形式储存。
int ret = nlsClient.SetLogConfig("nlsLog", LogLevel.LogDebug, 400, 10);
if (ret == 0)
nlsResult.Text = "OpenLog Success";
else
nlsResult.Text = "OpenLog Failed";
}
private void button1_Click_1(object sender, EventArgs e)
{
// 获取当前SDK的版本号
string version = nlsClient.GetVersion();
nlsResult.Text = version;
}
private void button1_Click_2(object sender, EventArgs e)
{
// -1则表示启动CPU核数的事件池数量,用于进行内部事件的处理。
// 单路调用的情况下,建议入参为1,即启动单个事件池进行处理。
// 高并发(几百路)的情况下,入参建议4 ~ CPU核数的三倍,入参越大,处理延迟越低但是CPU占用越高。
nlsClient.StartWorkThread(-1);
nlsResult.Text = "StartWorkThread and init NLS success.";
running = true;
Thread t = new Thread(FlushLab);
t.Start();
}
private void button1_Click_3(object sender, EventArgs e)
{
// 释放NlsClient,与StartWorkThread互为反操作
nlsClient.ReleaseInstance();
nlsResult.Text = "Release NLS success.";
}
#region Info
private void textBox1_TextChanged(object sender, EventArgs e)
{
akId = tAkId.Text;
}
private void tAppKey_TextChanged(object sender, EventArgs e)
{
appKey = tAppKey.Text;
}
private void tAkSecret_TextChanged(object sender, EventArgs e)
{
akSecret = tAkSecret.Text;
}
private void tToken_TextChanged(object sender, EventArgs e)
{
token = tToken.Text;
}
private void tUrl_TextChanged(object sender, EventArgs e)
{
url = tUrl.Text;
}
#endregion
#region TokenButton
// create token
private void button3_Click_1(object sender, EventArgs e)
{
int ret = -1;
tokenPtr = nlsClient.CreateNlsToken();
if (tokenPtr.native_token != IntPtr.Zero)
{
if (akId != null && akSecret != null & akId.Length > 0 && akSecret.Length > 0)
{
tokenPtr.SetAccessKeyId(tokenPtr, akId);
tokenPtr.SetKeySecret(tokenPtr, akSecret);
ret = tokenPtr.ApplyNlsToken(tokenPtr);
if (ret == -1)
{
System.Diagnostics.Debug.WriteLine("ApplyNlsToken failed");
nlsResult.Text = tokenPtr.GetErrorMsg(tokenPtr);
}
else
{
System.Diagnostics.Debug.WriteLine("ApplyNlsToken success");
token = tokenPtr.GetToken(tokenPtr);
tToken.Text = token;
expireTime = tokenPtr.GetExpireTime(tokenPtr);
nlsResult.Text = "ExpireTime:" + expireTime.ToString();
}
}
else
{
nlsResult.Text = "CreateToken Failed, akId or Secret is null";
}
}
else
{
nlsResult.Text = "CreateToken Failed";
}
}
// release token
private void button4_Click(object sender, EventArgs e)
{
if (tokenPtr.native_token != IntPtr.Zero)
{
nlsClient.ReleaseNlsToken(tokenPtr);
tokenPtr.native_token = IntPtr.Zero;
nlsResult.Text = "ReleaseNlsToken Success";
}
else
{
nlsResult.Text = "ReleaseNlsToken is nullptr";
}
}
#endregion
#region RecognizerCallback
private CallbackDelegate DemoOnRecognitionStarted =
(ref NLS_EVENT_STRUCT e) =>
{
System.Diagnostics.Debug.WriteLine("DemoOnRecognitionStarted = {0}", e.msg);
cur_sr_completed = "msg : " + e.msg;
sr_send_audio_flag = true;
};
private CallbackDelegate DemoOnRecognitionClosed =
(ref NLS_EVENT_STRUCT e) =>
{
System.Diagnostics.Debug.WriteLine("DemoOnRecognitionClosed = {0}", e.msg);
cur_sr_closed = "msg : " + e.msg;
};
private CallbackDelegate DemoOnRecognitionTaskFailed =
(ref NLS_EVENT_STRUCT e) =>
{
System.Diagnostics.Debug.WriteLine("DemoOnRecognitionTaskFailed = {0}", e.msg);
cur_sr_completed = "msg : " + e.msg;
sr_send_audio_flag = false;
sr_audio_loop_flag = false;
};
private CallbackDelegate DemoOnRecognitionResultChanged =
(ref NLS_EVENT_STRUCT e) =>
{
System.Diagnostics.Debug.WriteLine("DemoOnRecognitionResultChanged = {0}", e.msg);
cur_sr_result = "middle result : " + e.result;
};
private CallbackDelegate DemoOnRecognitionCompleted =
(ref NLS_EVENT_STRUCT e) =>
{
System.Diagnostics.Debug.WriteLine("DemoOnRecognitionCompleted = {0}", e.msg);
cur_sr_completed = "final result : " + e.result;
};
#endregion
// create recognizer
private void button8_Click(object sender, EventArgs e)
{
srPtr = nlsClient.CreateRecognizerRequest();
if (srPtr.native_request != IntPtr.Zero)
{
nlsResult.Text = "CreateRecognizerRequest Success";
}
else
{
nlsResult.Text = "CreateRecognizerRequest Failed";
}
cur_sr_result = "null";
cur_sr_closed = "null";
cur_sr_completed = "null";
}
// start recognizer
private void button6_Click(object sender, EventArgs e)
{
int ret = -1;
if (srPtr.native_request != IntPtr.Zero)
{
srPtr.SetAppKey(srPtr, appKey);
srPtr.SetToken(srPtr, token);
srPtr.SetUrl(srPtr, url);
srPtr.SetFormat(srPtr, "pcm");
srPtr.SetSampleRate(srPtr, 16000);
srPtr.SetIntermediateResult(srPtr, true);
srPtr.SetPunctuationPrediction(srPtr, true);
srPtr.SetInverseTextNormalization(srPtr, true);
srPtr.SetOnRecognitionStarted(srPtr, DemoOnRecognitionStarted, IntPtr.Zero);
srPtr.SetOnChannelClosed(srPtr, DemoOnRecognitionClosed, IntPtr.Zero);
srPtr.SetOnTaskFailed(srPtr, DemoOnRecognitionTaskFailed, IntPtr.Zero);
srPtr.SetOnRecognitionResultChanged(srPtr, DemoOnRecognitionResultChanged, IntPtr.Zero);
srPtr.SetOnRecognitionCompleted(srPtr, DemoOnRecognitionCompleted, IntPtr.Zero);
ret = srPtr.Start(srPtr);
if (sr_audio_loop_flag == false)
{
sr_audio_loop_flag = true;
sr_send_audio = new Thread(SRAudioLab);
sr_send_audio.Start();
}
}
if (ret != 0)
{
nlsResult.Text = "Recognizer Start failed";
}
else
{
nlsResult.Text = "Recognizer Start success";
}
}
// stop recognizer
private void button5_Click(object sender, EventArgs e)
{
int ret = -1;
if (srPtr.native_request != IntPtr.Zero)
ret = srPtr.Stop(srPtr);
sr_send_audio_flag = false;
sr_audio_loop_flag = false;
if (ret != 0)
{
nlsResult.Text = "Recognizer Stop failed";
}
else
{
nlsResult.Text = "Recognizer Stop success";
}
}
// release recognizer
private void button7_Click(object sender, EventArgs e)
{
if (srPtr.native_request != IntPtr.Zero)
{
nlsClient.ReleaseRecognizerRequest(srPtr);
srPtr.native_request = IntPtr.Zero;
nlsResult.Text = "ReleaseRecognizerRequest Success";
}
else
{
nlsResult.Text = "ReleaseRecognizerRequest is nullptr";
}
cur_sr_result = "null";
cur_sr_closed = "null";
cur_sr_completed = "null";
}
}
}