当前位置:手游汇攻略 → 教你如何用Unity制作一个类似Siri的问答软件

教你如何用Unity制作一个类似Siri的问答软件[图]

时间:2017-10-31 11:55:19    

在iPhone的siri刚刚推出时,很多用户都惊叹siri的IA之高,其实这类问答软件使用Unity也是可以做得出来的,下面手游汇小编就带来大神们用Unity制作的类似siri的问答代码吧!

大家好,我是云图。 之前项目有个需求要做一个简单的siri类似的问答系统,经过一番周折,终于还是实现出来了,软件不单可以在pc上面运行,也可以打包到安卓,ios平台,真正实现一键跨平台打包。

现在我们先说一些实现的思路,所谓问答系统,第一步就是用户首先说一句话,然后我们的软件把听到的话转换成文字。那现在问题有了,

第二步我们就需要一个地方,把我们的问题文字转化成我们软件回答的答案内容。

第三步就是把要回答的文字读出来。

思路有了,开始动手,首先,我们把用户输入的语音,要转成文字,经过我几个挑选,我发现百度语音和讯飞语音都不错,只不过讯飞语音的接入麻烦了点,

所以就采用了百度的语音识别

private string token; //access_token

private string cuid = "随便写的d"; //用户标识

private string format = "pcm"; //语音格式

private int rate = 8000; //采样率

private int channel = 1; //声道数

private string speech; //语音数据,进行base64编码

private int len; //原始语音长度

private string lan = "zh"; //语种

private string grant_Type = "client_credentials";

private string client_ID = "9152186"; //百度appkey

private string client_Secret = "14c703ce0f900eae40e95b2cdd564472"; //百度Secret Key

private string baiduAPI = "http://vop.baidu.com/server_api";

private string getTokenAPIPath =

"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=ekGb1G5XHY4BIVSA8nLzX5cA&client_secret=14c703ce0f900eae40e95b2cdd564472";

private Byte[] clipByte;

///

 

/// 转换出来的TEXT

///

public static string audioToString;

private AudioSource aud;

private int audioLength;//录音的长度

public void StartRecord()

{

Debug.Log("开始说话");

if (Microphone.devices.Length == 0) return;

Microphone.End(null);

aud.clip = Microphone.Start(null, false, 10, rate);

}

public void EndRecord()

{

Debug.Log("结束说话");

int lastPos = Microphone.GetPosition(null);

if (Microphone.IsRecording(null))

audioLength = lastPos / rate;//录音时长

else

audioLength = 10;

Microphone.End(null);

clipByte = GetClipData();

len = clipByte.Length;

speech = Convert.ToBase64String(clipByte);

StartCoroutine(GetToken(getTokenAPIPath));

StartCoroutine(GetAudioString(baiduAPI));

}

///

 

/// 把录音转换为Byte[]

///

///

public Byte[] GetClipData()

{

if (aud.clip == null)

{

Debug.LogError("录音数据为空");

return null;

}

float[] samples = new float[aud.clip.samples];

aud.clip.GetData(samples, 0);

Byte[] outData = new byte[samples.Length * 2];

int rescaleFactor = 32767; //to convert float to Int16

for (int i = 0; i < samples.Length; i )

{

short temshort = (short)(samples[i] * rescaleFactor);

Byte[] temdata = System.BitConverter.GetBytes(temshort);

outData[i * 2] = temdata[0];

outData[i * 2 1] = temdata[1];

}

if (outData == null || outData.Length <= 0)

{

Debug.LogError("录音数据为空");

return null;

}

return outData;

}

///

 

/// 获取百度用户令牌

///

/// 获取的url

///

private IEnumerator GetToken(string url)

{

WWW getTW = new WWW(url);

yield return getTW;

if (getTW.isDone)

{

if (getTW.error == null)

{

token = getTW.text;

StartCoroutine(GetAudioString(baiduAPI));

}

else

{

Debug.LogError("获取令牌出错" getTW.error);

}

}

else

{

Debug.LogError("下载出错" getTW.error);

}

}

///

 

/// 把语音转换为文字

///

///

///

private IEnumerator GetAudioString(string url)

{

JsonWriter jw = new JsonWriter();

jw.WriteObjectStart();

jw.WritePropertyName("format");

jw.Write(format);

jw.WritePropertyName("rate");

jw.Write(rate);

jw.WritePropertyName("channel");

jw.Write(channel);

jw.WritePropertyName("token");

jw.Write(token);

jw.WritePropertyName("cuid");

jw.Write(cuid);

jw.WritePropertyName("len");

jw.Write(len);

jw.WritePropertyName("speech");

jw.Write(speech);

jw.WriteObjectEnd();

WWW getASW = new WWW(url, Encoding.Default.GetBytes(jw.ToString()));

yield return getASW;

if (getASW.isDone)

{

if (getASW.error == null)

{

JsonData getASWJson = JsonMapper.ToObject(getASW.text);

if (getASWJson["err_msg"].ToString() == "success.")

{

audioToString = getASWJson["result"][0].ToString();

if (audioToString.Substring(audioToString.Length - 1) == ",")

audioToString = audioToString.Substring(0, audioToString.Length - 1);

Debug.Log("说话的问题是:" audioToString);

GetAnswer(audioToString);

}

else

{

Debug.LogWarning("没有成功:" getASWJson["err_msg"].ToString());

}

}

else

{

Debug.LogError(getASW.error);

}

}

}

首先你要去百度语音官网申请一个开发者权限,这些细节在这里就不讨论了,很简单。重要的就是两个参数 client_ID和client_Secret 的内容,填写到获取token的网页中发上去,获取到token后百度就知道我们是哪个用户哪个软件在调用语音识别了。这里在ios运行的时候有时候会显示获取不到token,原因是苹果不给我们这样发信息获取内容,说不安全,需要用其他办法。其他办法有很多,最笨的方法就是提前获取到token,然后写死在程序,坏处就是一个月会变一次,比较麻烦。好了,现在我们的语音已经传上百度然后转成文字下来, 下一步我采用的是图灵的文字问答系统。图灵这个做的也是非常好用的,直接把我们的问题文字写到url里面打开链接,就可以返回答案了。

private string url = "http://www.tuling123.com/openapi/api?key=d91b25b8866fef13f82cd28c0d523c8a&info=";

private string QuestionUrl= "http://www.tuling123.com/openapi/api?key=d91b25b8866fef13f82cd28c0d523c8a&info=";

public string msg = "";

///

 

/// 获取图灵返回的答案

///

/// 提问的问题

public void GetAnswer(string msg)

{

StartCoroutine(GetTuLingtoken(url msg));

}

private string TuLingtoken = "";

///

 

/// 图灵的问答系统

///

/// 要问的问题

///

private IEnumerator GetTuLingtoken(string url)

{

WWW getTW = new WWW(url);

yield return getTW;

if (getTW.isDone)

{

if (getTW.error == null)

{

TuLingtoken = getTW.text;

TuLingtoken = JsonMapper.ToObject(getTW.text)["text"].ToString();

PlayAudio(TuLingtoken);

}

else

{

Debug.LogError(getTW.error);

}

}

}

到这里我们就获取到我们要回答用户答案的音频了,回答的答案特别骚气。

教你如何用Unity制作一个类似Siri的问答软件[图]图片1

我相信到这一步很多做类似项目的也有不少人做到了,可就是这里没办法做下去了,为什么呢,

因为要用unity把网络的音频下载下来播放是非常麻烦的事情,我至今都没找到办法,就算用c#的办法解决了,可是安卓和ios呢,根本调用不了,再者就是就算你下载下来了,unity好像没有提供外部播放音频的功能,我不知道是我能力不足还是unity的问题,感觉很基本的事情居然没有解决方案。自我怀疑中。。。。

你可能要问了,那么有没

玩家评论

加载更多

网名(您的评论需要经过审核才能显示) 回复 [ ] 楼取消回复