Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器

目录

Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器
Unity 讯飞实时语音转写(二)—— 接收转写结果
Unity 讯飞实时语音转写(三)—— 分析转写结果

正文

老板前段时间有一个想法想要我出一个Demo,要用到实时语音转写,查找一些资料后,决定还是使用讯飞的实时语音转写。同时也在这里记录一下,方便以后同事介入。

一、创建应用
在讯飞控制台上创建一个应用。
Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器_第1张图片

点击应用,记录下appid、appkey
Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器_第2张图片
二、根据开发文档,编写测试案例

代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using UnityEngine;

public class TestConnect : MonoBehaviour
{
    private string appid = "xxxx";
    private string appkey = "xxxxxxxxx";

    private string timeStamp;
    private string baseString;
    private string toMd5;

    private string signa;
    private ClientWebSocket ws;
    private CancellationToken ct;

    // Start is called before the first frame update
    void Start()
    {
        Connect();
    }

    private async void Connect()
    {
        try
        {
            ws = new ClientWebSocket();
            ct = new CancellationToken();
            Uri uri = GetUri();
            await ws.ConnectAsync(uri, ct);

            //await ws.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes("{\"end\": true}")), WebSocketMessageType.Binary, true, ct); //发送数据
            while (true)
            {
                var result = new byte[1024];
                await ws.ReceiveAsync(new ArraySegment<byte>(result), new CancellationToken()); //接受数据
                var str = Encoding.UTF8.GetString(result, 0, result.Length);
                Debug.Log("Return String: " + str);
            }
        }
        catch (Exception ex)
        {
            Debug.Log("Exception Msg: " + ex.Message);
            ws.Dispose();
        }
    }

    /// 
    /// 获得请求URI
    /// 
    /// 
    private Uri GetUri()
    {
        //精确到秒
        timeStamp = GetTimeStamp();

        //baseString由appid和当前时间戳ts拼接而成
        baseString = appid + timeStamp;

        //对baseString进行MD5
        toMd5 = ToMD5(baseString);

        //以apiKey为key对MD5之后的baseString进行HmacSHA1加密
        //然后再对加密后的字符串进行base64编码
        signa = ToHmacSHA1(toMd5, appkey);

        string requestUrl = string.Format("wss://rtasr.xfyun.cn/v1/ws?appid={0}&ts={1}&signa={2}&pd=tech", appid,
            timeStamp, UrlEncode(signa));
        Debug.Log("requestUrl: " + requestUrl);
        return new Uri(requestUrl);
    }

    /// 
    /// 对字符串进行UrlEncode转码
    /// 
    /// 需要转码的字符串
    /// 
    public static string UrlEncode(string str)
    {
        StringBuilder sb = new StringBuilder();
        byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
        for (int i = 0; i < byStr.Length; i++)
        {
            sb.Append(@"%" + Convert.ToString(byStr[i], 16));
        }

        return (sb.ToString());
    }

    /// 
    /// 获取时间戳
    /// 
    /// 返回的时间戳,精确到秒
    public static string GetTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString();
    }

    /// 
    /// MD5字符串加密
    /// 
    /// 需要加密的字符串
    /// 加密后字符串
    public static string ToMD5(string txt)
    {
        using (MD5 mi = MD5.Create())
        {
            byte[] buffer = Encoding.Default.GetBytes(txt);
            //开始加密
            byte[] newBuffer = mi.ComputeHash(buffer);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < newBuffer.Length; i++)
            {
                sb.Append(newBuffer[i].ToString("x2"));
            }

            return sb.ToString();
        }
    }

    /// 
    /// HMACSHA1算法加密并返回ToBase64String
    /// 
    /// 要加密的原串
    ///私钥
    /// 返回一个签名值(即哈希值)
    public static string ToHmacSHA1(string text, string key)

    {
        //HMACSHA1加密
        HMACSHA1 hmacsha1 = new HMACSHA1();
        hmacsha1.Key = System.Text.Encoding.UTF8.GetBytes(key);

        byte[] dataBuffer = System.Text.Encoding.UTF8.GetBytes(text);
        byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

        return Convert.ToBase64String(hashBytes);
    }
}

把脚本中的appid、appkey的值赋成刚才创建应用的地方的值,
然后把这个脚本随便挂在场景的一个对象上,运行。得到以下结果说明成功脸上了服务器。
在这里插入图片描述

如果有错误,请根据错误代码,检查对应的值是否设置正确。

对了,如果只是握手阶段并未发送音频字节,所以一段时间后远端服务器会自动断开,如下:
在这里插入图片描述

其实只要确定appid、appkey正确填写,肯定就不会有什么问题啦。

转载注明出处!

你可能感兴趣的:(笔记,Unity3D,unity)