目录
Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器
Unity 讯飞实时语音转写(二)—— 接收转写结果
Unity 讯飞实时语音转写(三)—— 分析转写结果
正文
老板前段时间有一个想法想要我出一个Demo,要用到实时语音转写,查找一些资料后,决定还是使用讯飞的实时语音转写。同时也在这里记录一下,方便以后同事介入。
一、创建应用
在讯飞控制台上创建一个应用。
点击应用,记录下appid、appkey
二、根据开发文档,编写测试案例
代码如下:
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<byte>(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();
}
}
/// <summary>
/// 获得请求URI
/// </summary>
/// <returns></returns>
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);
}
/// <summary>
/// 对字符串进行UrlEncode转码
/// </summary>
/// <param name="str">需要转码的字符串</param>
/// <returns></returns>
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());
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns>返回的时间戳,精确到秒</returns>
public static string GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/// <summary>
/// MD5字符串加密
/// </summary>
/// <param name="txt">需要加密的字符串</param>
/// <returns>加密后字符串</returns>
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();
}
}
/// <summary>
/// HMACSHA1算法加密并返回ToBase64String
/// </summary>
/// <param name="text">要加密的原串</param>
///<param name="key">私钥</param>
/// <returns>返回一个签名值(即哈希值)</returns>
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正确填写,肯定就不会有什么问题啦。
转载注明出处!