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

alibabacloud-nls-cpp-sdk3.1.14-master_3bf92a9.zip

SDK源码

f5f951190fbc10b39c41239f0483758e

NlsCsharpSdk_Windows_3.1.14_3bf92a9.zip

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#编译运行

编译第三方库

此方式使用已经编译好的第三方库进行编译,首先编译Windows平台Cpp SDK库。

  1. 下载alibabacloud-nls-cpp-sdk<version>-master_<github commit id>.zip并解压到本地,或从GitHub获取最新代码。

  2. 进入scripts目录,使用文本编辑工具分别打开build_windows_64_prebuild.batbuild_windows_64_package.bat,修改解压缩工具WinRAR。

    例如,您的个人电脑WinRAR.exe所在路径为C:\Program Files (x86)\WinRAR\WinRAR.exe,则修改脚本文件中第三行为set winRar="C:\Program Files (x86)\WinRAR\WinRAR.exe" 为您的个人电脑中WinRAR路径。

  3. 双击批处理脚本build_windows_64_prebuild.bat,从而解压SDK源码中包含的各第三方库,并把依赖头文件释放到合适位置。

  4. 使用Visual Studio(VS2015及以上版本)打开nlsCppSdk.sln,直接编译需要的范例工程。

    说明
    • 需要确认好各项目属性中的目标平台版本平台工具集,按需选择。例如,您的目标平台版本10.0.19041.0平台工具集Visual Studio 2015(v140)

    • 目前支持Debug_x64,Release_x64,Debug_win32和Release_win32。本文档说明均以x64为例。

  5. 右键单击speechSynthesizerDemo项目,单击生成进行编译。

  6. 编译Debug_x64和Release_x64。

    • Debug生成物路径:{ProjectRoot}\build\build_win64\nlsCppSdk\x64\Debug

    • Release生成物路径:{ProjectRoot}\build\build_win64\nlsCppSdk\x64\Release

    各路径包含所有生成的dll和测试exe。其中{ProjectRoot}为SDK源码路径。

  7. 若需要对生成的库文件、测试exe、头文件、说明文档等对外披露的文件进行打包,则在scripts目录下双击运行build_windows_64_package.bat,生成{ProjectRoot}\build\install\NlsSdk3.X_win64.zip。其中{ProjectRoot}为SDK源码路径。

C#编译

必须先完成Windows平台Cpp SDK编译,C#依赖Windows Cpp SDK的库和头文件。完成以上编译后开始进行C#编译。

  1. 使用Visual Studio(VS2015及以上版本)打开nlsCsharpSdk.sln,进行C#工程编译。

    说明

    需要确认nlsCsharpSdkExtern平台工具集目标平台版本,以及nlsCsharpSdkDemonlsCsharpSdk的.NET版本。

  2. 右键nlsCsharpSdkDemo项目,选择生成,生成所有生成物。C#编译

    说明

    {ProjectRoot}\nlsCsharpSdk\nlsCsharpSdkDemo\bin\Debug路径下包含所有生成物,{ProjectRoot}为SDK源码路径。

    • nlsCsharpSdk.dll为NLS C# SDK,可进行发布Nupkg。

    • nlsCsharpSdkExtern.dll为NLS C#与Cpp互操作层。

    • nlsCsharpSdkDemo.exe为NLS C# UI Demo。

  3. 以Debug版本为例,运行还需要一些NLS Cpp SDK相关依赖库,需要将依赖库搬移到nlsCsharpSdkDemo.exe能依赖的路径:{ProjectRoot}\nlsCsharpSdk\nlsCsharpSdkDemo\bin\Debug。即分别将下方动态库拷贝至 {ProjectRoot}\nlsCsharpSdk\nlsCsharpSdkDemo\bin\Debug目录下。

    说明

    正常情况下在工程编译完成后系统会进行自动搬运,您可跳过此步骤。若目标路径无以下文件,则需要进行手动搬运。

    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\nlsCppSdk.dll
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\libcrypto-1_1-x64.dll 
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\libssl-1_1-x64.dll 
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\libcurld.dll (release版为libcurl.dll) 
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\libeay32.dll 
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\ssleay32.dll 
    {ProjectRoot}\build\install\NlsSdk3.X_win64\lib\14.0\x64\Debug\pthreadVC2.dll 

    {ProjectRoot}\nlsCsharpSdk\nlsCsharpSdkDemo\bin\Debug\audio_files\ 目录下,需要包含命名为test0.wav、test1.wav、test2.wav、test3.wav的四个音频文件,用于进行语音识别。这些WAV文件可从resource/audio目录拷贝。若缺少这些文件,系统将会在运行语音识别过程中,因找不到文件而退出。

  4. 双击nlsCsharpSdkDemo.exe,运行如下:编译

  5. (可选)单击OpenLog可开启日志记录。

  6. 单击InitNls初始化SDK。

  7. 填入Appkey、AccessKey ID、AccessKey Secret后,单击CreateToken生成Token,合法Token会在Token栏显示。

  8. 单击CreateSynthesizer创建语音合成请求,然后单击Start开始工作,会在nlsCsharpSdkDemo.exe所在路径生成保存音频数据的<taskId>.pcm文件,单击Stop后停止工作,然后单击ReleaseTranscriber释放请求。

关键接口

using nlsCsharpSdk;
  • 基础接口

    • NlsClient:语音处理客户端,利用该客户端可以进行一句话识别、实时语音识别和语音合成的语音处理任务。该客户端为线程安全,建议全局仅创建一个实例。

      接口名

      功能描述

      SetLogConfig

      设置日志文件与存储路径。

      StartWorkThread

      启动工作线程数,默认1即启动一个线程,若-1则启动CPU核数的线程数。在高并发的情况下建议选择-1。这一接口有初始化NlsClient的作用。

      ReleaseInstance

      销毁NlsClient对象实例,即释放NLS SDK。

      GetVersion

      获取SDK版本号。

      CreateSynthesizerRequest

      创建语音合成对象,线程安全,支持高并发请求。

      CreateSynthesizerRequest

      销毁语音合成对象,需要在当前请求的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

      获取云端返回的识别结果。

  • 识别接口

    SpeechSynthesizerRequest:语音合成请求对象,用于语音合成及长文本语音合成。

    接口名

    功能描述

    SetOnSynthesisCompleted

    设置语音合成结束回调函数。

    SetOnChannelClosed

    设置通道关闭回调函数。

    SetOnTaskFailed

    设置错误回调函数。

    SetOnBinaryDataReceived

    设置语音合成二进制音频数据接收回调函数。

    SetOnMetaInfo

    设置文本对应的日志信息接收回调函数。

    SetAppKey

    设置Appkey。

    SetToken

    口令认证。所有的请求都必须通过SetToken方法认证通过,才可以使用。

    SetUrl

    设置服务URL地址。

    SetText

    待合成音频文本内容text设置。

    SetVoice

    发音人voice设置。

    SetVolume

    音量volume设置。

    SetFormat

    输出音频编码格式Format设置。

    SetSampleRate

    音频采样率设置。

    SetSpeechRate

    语速设置。

    SetPitchRate

    语调设置。

    SetEnableSubtitle

    是否开启字幕功能。

    Start

    启动SpeechSynthesizerRequest。

    Cancel

    不会与服务端确认关闭,直接关闭语音合成过程。

错误码

错误码

错误描述

解决方案

10000001

SSL: couldn’t create a …!

建议重试。

10000002

openssl官方错误描述

根据描述提示处理后,重试。

10000003

系统错误描述

根据系统错误描述提示处理。

10000004

URL: The url is empty.

检查是否设置云端URL地址。

10000005

URL: Could not parse WebSocket url.

检查是否正确设置云端URL地址。

10000006

MODE: unsupport mode.

检查是否正确设置了语音功能模式。

10000007

JSON: Json parse failed.

服务端发送错误响应内容,请提供task_id,并反馈给阿里云。

10000008

WEBSOCKET: unkown head type.

服务端发送错误WebSocket类型,请提供task_id,并通过工单系统反馈给我们。

10000009

HTTP: connect failed.

与云端连接失败,请检查网络后,重试。

HTTP协议官方状态码

HTTP: Got bad status.

根据HTTP协议官方描述提示处理。

系统错误码

IP: ip address is not valid.

根据系统错误描述提示处理。

系统错误码

ENCODE: convert to utf8 error.

根据系统错误描述提示处理。

10000010

please check if the memory is enough.

内存不足,请检查本地机器内存。

10000011

Please check the order of execution.

接口调用顺序错误(接收到Failed/complete事件时,SDK内部会关闭连接。此时再调用send方法会上报错误)。

10000012

StartCommand/StopCommand Send failed.

参数错误。请检查参数设置是否正确。

10000013

The sent data is null or dataSize &amp;lt;= 0.

发送错误。请检查发送参数是否正确。

10000014

Start invoke failed.

调用start方法超时错误。请调用stop方法释放资源,重新开始识别流程。

10000015

connect failed.

调用connect方法失败。请调用stop方法释放资源,重新开始识别流程。

服务端响应状态码

关于服务状态码,请参见服务状态码

代码示例

说明

  • 示例中使用的音频文件为16000 Hz采样率,管控台设置的模型为通用模型。如果使用其他音频,请设置为支持该音频场景的模型。关于模型设置,请参见管理项目

  • 示例中使用了SDK内置的默认语音合成服务的外网访问服务URL,如果您使用阿里云上海ECS且需要使用内网访问URL,则在创建SpeechSynthesizerRequest的对象中设置内网访问的URL。

    SpeechSynthesizerRequest 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 SpeechSynthesizerRequest syPtr;
        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 string cur_sy_completed;
        static string cur_sy_closed;

        private void FlushLab()
        {
            while (running)
            {
                if (cur_nls_result != null && cur_nls_result.Length > 0)
                {
                    nlsResult.Text = cur_nls_result;
                }

                if (cur_st_result != null && cur_st_result.Length > 0)
                {
                    stResult.Text = cur_st_result;
                }
                if (cur_st_completed != null && cur_st_completed.Length > 0)
                {
                    stCompleted.Text = cur_st_completed;
                }
                if (cur_st_closed != null && cur_st_closed.Length > 0)
                {
                    stClosed.Text = cur_st_closed;
                }

                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;
                }

                if (cur_sy_completed != null && cur_sy_completed.Length > 0)
                {
                    syCompleted.Text = cur_sy_completed;
                }
                if (cur_sy_closed != null && cur_sy_closed.Length > 0)
                {
                    syClosed.Text = cur_sy_closed;
                }
                Thread.Sleep(200);
            }
        }

        public nlsCsharpSdkDemo()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false

            nlsClient = new NlsClient();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            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)
        {
            string version = nlsClient.GetVersion();
            nlsResult.Text = version;
        }

        private void button1_Click_2(object sender, EventArgs e)
        {
            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.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 SynthesizerCallback
        private CallbackDelegate DemoOnBinaryDataReceived =
            (ref NLS_EVENT_STRUCT e) =>
            {
                FileStream fs;
                String filename = e.taskId + ".pcm";
                if (File.Exists(filename))
                {
                    fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
                }
                else
                {
                    fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
                }
                fs.Write(e.binaryData, 0, e.binaryDataSize);
                fs.Close();
            };
        private CallbackDelegate DemoOnSynthesisClosed =
            (ref NLS_EVENT_STRUCT e) =>
            {
                System.Diagnostics.Debug.WriteLine("DemoOnSynthesisClosed = {0}", e.msg);
                cur_sy_closed = "msg : " + e.msg;
            };
        private CallbackDelegate DemoOnSynthesisTaskFailed =
            (ref NLS_EVENT_STRUCT e) =>
            {
                System.Diagnostics.Debug.WriteLine("DemoOnSynthesisTaskFailed = {0}", e.msg);
                cur_sy_completed = "msg : " + e.msg;
            };
        private CallbackDelegate DemoOnSynthesisCompleted =
            (ref NLS_EVENT_STRUCT e) =>
            {
                System.Diagnostics.Debug.WriteLine("DemoOnSynthesisCompleted = {0}", e.msg);
                cur_sy_completed = "result : " + e.msg;
            };
        private CallbackDelegate DemoOnMetaInfo =
            (ref NLS_EVENT_STRUCT e) =>
            {
                System.Diagnostics.Debug.WriteLine("DemoOnMetaInfo = {0}", e.msg);
                //cur_sy_completed = "metaInfo : " + e.msg;
            };
        #endregion

        // create synthesizer
        private void button12_Click(object sender, EventArgs e)
        {
            syPtr = nlsClient.CreateSynthesizerRequest(TtsVersion.ShortTts);
            if (syPtr.native_request != IntPtr.Zero)
            {
                nlsResult.Text = "CreateSynthesizerRequest Success";
            }
            else
            {
                nlsResult.Text = "CreateSynthesizerRequest Failed";
            }
            cur_sy_closed = "null";
            cur_sy_completed = "null";
        }

        // start synthesizer
        private void button10_Click(object sender, EventArgs e)
        {
            int ret = -1;
            if (syPtr.native_request != IntPtr.Zero)
            {
                syPtr.SetAppKey(syPtr, appKey);
                syPtr.SetToken(syPtr, token);
                syPtr.SetUrl(syPtr, url);
                syPtr.SetText(syPtr, "今天天气真不错,我想去操场踢足球。");
                syPtr.SetVoice(syPtr, "siqi");
                syPtr.SetVolume(syPtr, 50);
                syPtr.SetFormat(syPtr, "wav");
                syPtr.SetSampleRate(syPtr, 16000);
                syPtr.SetSpeechRate(syPtr, 0);
                syPtr.SetPitchRate(syPtr, 0);
                syPtr.SetEnableSubtitle(syPtr, true);

                syPtr.SetOnSynthesisCompleted(syPtr, DemoOnSynthesisCompleted, IntPtr.Zero);
                syPtr.SetOnBinaryDataReceived(syPtr, DemoOnBinaryDataReceived, IntPtr.Zero);
                syPtr.SetOnTaskFailed(syPtr, DemoOnSynthesisTaskFailed, IntPtr.Zero);
                syPtr.SetOnChannelClosed(syPtr, DemoOnSynthesisClosed, IntPtr.Zero);
                syPtr.SetOnMetaInfo(syPtr, DemoOnMetaInfo, IntPtr.Zero);

                ret = syPtr.Start(syPtr);
            }

            if (ret != 0)
            {
                nlsResult.Text = "Synthesizer Start failed";
            }
            else
            {
                nlsResult.Text = "Synthesizer Start success";
            }
        }

        // cancel synthesizer
        private void button9_Click(object sender, EventArgs e)
        {
            int ret = -1;
            if (syPtr.native_request != IntPtr.Zero)
                ret = syPtr.Cancel(syPtr);

            if (ret != 0)
            {
                nlsResult.Text = "Synthesizer Cancel failed";
            }
            else
            {
                nlsResult.Text = "Synthesizer Cancel success";
            }
        }

        private void btnSYrelease_Click(object sender, EventArgs e)
        {
            if (syPtr.native_request != IntPtr.Zero)
            {
                nlsClient.ReleaseSynthesizerRequest(syPtr);
                syPtr.native_request = IntPtr.Zero;
                nlsResult.Text = "ReleaseSynthesizerRequest Success";
            }
            else
            {
                nlsResult.Text = "ReleaseSynthesizerRequest is nullptr";
            }
            cur_sy_closed = "null";
            cur_sy_completed = "null";
        }
    }
}
阿里云首页 智能语音交互 相关技术圈