这篇文章主要讲解了“C# Unity怎么接入腾讯云实时语音识别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C# Unity怎么接入腾讯云实时语音识别”吧!
引入腾讯的 c# sdk中的工具类
https://github.com/TencentCloud/tencentcloud-sdk-dotnet
签名工具类
https://github.com/TencentCloud/tencentcloud-sdk-dotnet/blob/master/TencentCloud/Common/Sign.cs
https://github.com/TencentCloud/tencentcloud-sdk-dotnet/blob/master/TencentCloud/Common/Profile/ClientProfile.cs
https://github.com/TencentCloud/tencentcloud-sdk-dotnet/blob/master/TencentCloud/Common/Profile/HttpProfile.cs
以Unity中为例接入腾讯云实时语音识别
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
// using Newtonsoft.Json;
using UnityEngine.UI;
using System.Linq;
using UnityEngine.Events;
using TencentCloud.Common.Profile;
using TencentCloud.Common;
using sami.pegamob;
[Serializable]
public struct TencentAsrResponse
{
public int code;
public string message;
public string voice_id;
public string message_id;
[SerializeField] public Result result;
[Serializable]
public struct Result
{
public int slice_type;
public int index;
public int start_time;
public int end_time;
public string voice_text_str;
public int word_size;
[Serializable]
public struct Word
{
public string word;
public int start_time;
public int end_time;
public int stable_flag;
}
[SerializeField] public Word[] word_list;
}
public int final;
}
public class TencentAsr : MonoBehaviour
{
public string appid;
public string secretid;
public string secretkey;
public string timestamp;
public string expired;
public string nonce;
public string engine_model_type;
public string voice_id;
public string voice_format;
public string signature;
public bool pausing;
/*
1251200071
SecretId: AKIDDDm46Af1at9VNyNlFDvfDr0vbgWwh0kE
SecretKey: OXOXEfp7QHsCjTwA76UcU5SZTD7qJcl1
*/
public SortedDictionary<string, string> asrParams = new SortedDictionary<string, string>();
public AudioClip RecordedClip;
private ClientWebSocket ws;
private CancellationToken ct;
//最大录音时长
private int MAX_RECORD_LENGTH = 1000;//3599
/// <summary>
/// 语音识别回调事件
/// </summary>
public event Action<string> asrCallback;
public Transform notifyTarget;
// Start is called before the first frame update
private void OnApplicationQuit()
{
//StopASR();
}
//wss://asr.cloud.tencent.com/asr/v2/1259228442?engine_model_type=16k_zh&expired=1592380492&filter_dirty=1&filter_modal=1&filter_punc=1&needvad=1&nonce=1592294092123&secretid=AKIDoQq1zhZMN8dv0psmvud6OUKuGPO7pu0r×tamp=1592294092&voice_format=1&voice_id=RnKu9FODFHK5FPpsrN&signature=HepdTRX6u155qIPKNKC%2B3U0j1N0%3D
//wss://asr.cloud.tencent.com/asr/v2/1251200071?engine_model_type=16k_en&expired=1617808000&nonce=1592294092123&secretid=AKIDDDm46Af1at9VNyNlFDvfDr0vbgWwh0kE×tamp=1617721600&voice_format=1&voice_id=RnKu9FODFHK5FPpsrN&signature=T1RkUFNuSEJtZXdHbE1XMEJzSFRuRFBFWEVvPQ%3d%3d
private Uri GetUri()
{
appid = "1251200071";
secretid = "AKIDDDm46Af1at9VNyNlFDvfDr0vbgWwh0kE";
secretkey = "OXOXEfp7QHsCjTwA76UcU5SZTD7qJcl1";
timestamp = SamiTool.GetTimeStamp();
expired = (SamiTool.GetTimeStampInt() + 24 * 3600).ToString();
nonce = "1592294092123";//TODO随机一个
engine_model_type = "16k_en";
voice_id = "RnKu9FODFHK5FPpsrN";//TODO随机一个
voice_format = "1";
asrParams.Add("secretid", secretid);
asrParams.Add("timestamp", timestamp);
asrParams.Add("expired", expired);
asrParams.Add("nonce", nonce);
asrParams.Add("engine_model_type", engine_model_type);
asrParams.Add("voice_id", voice_id);
asrParams.Add("voice_format", voice_format);
//word_info
asrParams.Add("word_info", "1");
string str = "asr.cloud.tencent.com/asr/v2/"+appid+"?" + SignHelper.BuildParamStr(asrParams);
Debug.Log(str);
Debug.Log(secretkey);
signature = SamiTool.ToHmacSHA1(str,secretkey);
Debug.Log(str);
Debug.Log(signature);
string url = "wss://" + str + "&signature=" + WWW.EscapeURL(signature);
//string url = "wss://" + str + "&signature=" + signature;
Debug.Log(url);
return new Uri(url);
}
public void ConnectAsr()
{
//Uri asrUri = GetUri();
StartASR();
}
public bool IsWsConnected()
{
bool connected = false;
if (ws == null)
{
connected = false;
}
else
{
Debug.Log(ws.State);
connected = (ws.State == WebSocketState.Connecting) || (ws.State == WebSocketState.Open);
}
return connected;
}
public void StartASR()
{
if (ws != null && ws.State == WebSocketState.Connecting)
{
Debug.LogWarning("上次识别连接中");
return;
}
if (ws != null && ws.State == WebSocketState.Open)
{
Debug.LogWarning("开始语音识别失败!,等待上次识别连接结束");
return;
}
if (Microphone.devices.Length == 0)
{
Debug.LogError("未检测到可用的麦克风");
return;
}
ConnectASR_Aysnc();
RecordedClip = Microphone.Start(null, false, MAX_RECORD_LENGTH, 16000);
}
public async void StopASR()
{
Debug.Log("VC StopASR");
if (ws != null)
{
//关掉发送音频的协程
StopCoroutine(SendAudioClip());
//Debug.Log("发送结束标识" + ws.State);
//音频数据上传完成后,客户端需发送一个 {"type": "end"} 到服务端作为结束标识
try
{
await ws.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes("{\"type\": \"end\"}")),WebSocketMessageType.Binary,true, new CancellationToken());
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "关闭WebSocket连接", new CancellationToken());
ws.Dispose();
}
catch (System.Exception)
{
throw;
}
Microphone.End(null);
StartCoroutine(StopRecord());
}
}
private IEnumerator StopRecord()
{
yield return new WaitUntil(() => ws.State != WebSocketState.Open);
Debug.Log("识别结束,停止录音");
}
async void ConnectASR_Aysnc()
{
ws = new ClientWebSocket();
ct = new CancellationToken();
Uri url = GetUri();
await ws.ConnectAsync(url, ct);
StartCoroutine(SendAudioClip());
StringBuilder stringBuilder = new StringBuilder();
while (ws.State == WebSocketState.Open)
{
var result = new byte[4096];
await ws.ReceiveAsync(new ArraySegment<byte>(result), ct); //接受数据
List<byte> list = new List<byte>(result);
while (list[list.Count - 1] == 0x00) list.RemoveAt(list.Count - 1); //去除空字节
string str = Encoding.UTF8.GetString(list.ToArray());
if (string.IsNullOrEmpty(str))
{
return;
}
try
{
TencentAsrResponse jsonData = JsonUtility.FromJson<TencentAsrResponse>(str);
if (jsonData.code == 0)
{
if (jsonData.message_id != null)
{
AnalysisResult(jsonData);
}
else
{
Debug.Log("握手成功!");
Debug.Log(str);
}
}
else
{
Debug.Log("Error: " + jsonData.message);
}
}
catch (Exception ex)
{
Debug.LogError(ex.Message + str);
}
}
Debug.LogWarning("断开连接");
}
IEnumerator SendAudioClip()
{
yield return new WaitWhile(() => Microphone.GetPosition(null) <= 0);
float t = 0;
int position = Microphone.GetPosition(null);
const float waitTime = 0.04f; //每隔40ms发送音频
const int Maxlength = 1280; //最多发送1280字节
int status = 0;
int lastPosition = 0;
while (position < RecordedClip.samples && ws.State == WebSocketState.Open)
{
t += waitTime;
if (t >= MAX_RECORD_LENGTH)
{
Debug.Log("录音时长已用尽,结束语音识别!");
break;
}
yield return new WaitForSecondsRealtime(waitTime);
if (Microphone.IsRecording(null))
{
position = Microphone.GetPosition(null);
//Debug.Log("录音时长:" + t + "position=" + position + ",lastPosition=" + lastPosition);
}
if (position <= lastPosition)
{
// 防止出现当前采样位置和上一帧采样位置一样,导致length为0
// 那么在调用AudioClip.GetData(float[] data, int offsetSamples);时,将报错
continue;
}
if (!pausing)
{
int length = position - lastPosition > Maxlength ? Maxlength : position - lastPosition;
byte[] data = GetAudioClip(lastPosition, length, RecordedClip);
// byte[] data = GetAudioClip(lastPosition, length, clipTest);
ws.SendAsync(new ArraySegment<byte>(data), WebSocketMessageType.Binary, true,
new CancellationToken()); //发送数据
lastPosition = lastPosition + length;
status = 1;
}
}
}
public virtual void AnalysisResult(TencentAsrResponse tencentAsrResponse)
{
if(tencentAsrResponse.result.voice_text_str!=null&& tencentAsrResponse.result.voice_text_str!="")
{
//Debug.Log(tencentAsrResponse.result.voice_text_str);
if (notifyTarget != null)
{
notifyTarget.SendMessage("OnWords", tencentAsrResponse);
}
}
}
public static byte[] GetAudioClip(int start, int length, AudioClip recordedClip)
{
float[] soundata = new float[length];
recordedClip.GetData(soundata, start);
int rescaleFactor = 32767;
byte[] outData = new byte[soundata.Length * 2];
for (int i = 0; i < soundata.Length; i++)
{
short temshort = (short)(soundata[i] * rescaleFactor);
byte[] temdata = BitConverter.GetBytes(temshort);
outData[i * 2] = temdata[0];
outData[i * 2 + 1] = temdata[1];
}
return outData;
}
public static string saveTempWave(int start,int length, AudioClip recordedClip)
{
float[] soundata = new float[length];
recordedClip.GetData(soundata, start);
AudioClip tempClip = AudioClip.Create("tempwav",length,recordedClip.channels,recordedClip.frequency,false);
tempClip.SetData(soundata,0);
string tempwave = "";
WavUtility.FromAudioClip (tempClip, out tempwave, true);
Debug.Log(tempwave);
return tempwave;
}
}
感谢各位的阅读,以上就是“C# Unity怎么接入腾讯云实时语音识别”的内容了,经过本文的学习后,相信大家对C# Unity怎么接入腾讯云实时语音识别这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/186935/blog/5011303