小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【新提醒】【unity制作一個(gè)Siri問答軟件】

 鴻蛟家平 2017-10-20
大家好,我是云圖。 之前項(xiàng)目有個(gè)需求要做一個(gè)簡(jiǎn)單的siri類似的問答系統(tǒng),經(jīng)過一番周折,終于還是實(shí)現(xiàn)出來了,軟件不單可以在pc上面運(yùn)行,也可以打包到安卓,ios平臺(tái),真正實(shí)現(xiàn)一鍵跨平臺(tái)打包。

   現(xiàn)在我們先說一些實(shí)現(xiàn)的思路,所謂問答系統(tǒng),第一步就是用戶首先說一句話,然后我們的軟件把聽到的話轉(zhuǎn)換成文字。那現(xiàn)在問題有了,
第二步我們就需要一個(gè)地方,把我們的問題文字轉(zhuǎn)化成我們軟件回答的答案內(nèi)容。
第三步就是把要回答的文字讀出來。
   思路有了,開始動(dòng)手,首先,我們把用戶輸入的語音,要轉(zhuǎn)成文字,經(jīng)過我?guī)讉€(gè)挑選,我發(fā)現(xiàn)百度語音和訊飛語音都不錯(cuò),只不過訊飛語音的接入麻煩了點(diǎn),
所以就采用了百度的語音識(shí)別
[C#] 純文本查看 復(fù)制代碼
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#region 錄制聲音轉(zhuǎn)化為文字
private string token;                           //access_token
private string cuid = "隨便寫的d";        //用戶標(biāo)識(shí)
private string format = "pcm";                  //語音格式
private int rate = 8000;                        //采樣率
private int channel = 1;                        //聲道數(shù)
private string speech;                          //語音數(shù)據(jù),進(jìn)行base64編碼
private int len;                                //原始語音長(zhǎng)度
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./oauth/2.0/token?grant_type=client_credentials&client_id=ekGb1G5XHY4BIVSA8nLzX5cA&client_secret=14c703ce0f900eae40e95b2cdd564472";
private Byte[] clipByte;
/// <summary>
/// 轉(zhuǎn)換出來的TEXT
/// </summary>
public static string audioToString;
private AudioSource aud;
private int audioLength;//錄音的長(zhǎng)度
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("結(jié)束說話");
    int lastPos = Microphone.GetPosition(null);
    if (Microphone.IsRecording(null))
        audioLength = lastPos / rate;//錄音時(shí)長(zhǎng) 
    else
        audioLength = 10;
    Microphone.End(null);
    clipByte = GetClipData();
    len = clipByte.Length;
    speech = Convert.ToBase64String(clipByte);
    StartCoroutine(GetToken(getTokenAPIPath));
    StartCoroutine(GetAudioString(baiduAPI));
}
/// <summary>
/// 把錄音轉(zhuǎn)換為Byte[]
/// </summary>
/// <returns></returns>
public Byte[] GetClipData()
{
    if (aud.clip == null)
    {
        Debug.LogError("錄音數(shù)據(jù)為空");
        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);
      [/i]  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("錄音數(shù)據(jù)為空");
        return null;
    }
      
    return outData;
}
/// <summary>
/// 獲取百度用戶令牌
/// </summary>
/// <param name="url">獲取的url</param>
/// <returns></returns>
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("獲取令牌出錯(cuò)" + getTW.error);
        }
    }
    else
    {
        Debug.LogError("下載出錯(cuò)" + getTW.error);
    }
}
/// <summary>
/// 把語音轉(zhuǎn)換為文字
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
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);
        }
    }
}
#endregion



首先你要去百度語音官網(wǎng)申請(qǐng)一個(gè)開發(fā)者權(quán)限,這些細(xì)節(jié)在這里就不討論了,很簡(jiǎn)單。重要的就是兩個(gè)參數(shù) client_ID和client_Secret 的內(nèi)容,
填寫到獲取token的網(wǎng)頁(yè)中發(fā)上去,獲取到token后百度就知道我們是哪個(gè)用戶哪個(gè)軟件在調(diào)用語音識(shí)別了。這里在ios運(yùn)行的時(shí)候有時(shí)候會(huì)顯示獲取不到token,
原因是蘋果不給我們這樣發(fā)信息獲取內(nèi)容,說不安全,需要用其他辦法。其他辦法有很多,最笨的方法就是提前獲取到token,然后寫死在程序,壞處就是一個(gè)月會(huì)變一次,比較麻煩。
好了,現(xiàn)在我們的語音已經(jīng)傳上百度然后轉(zhuǎn)成文字下來, 下一步我采用的是圖靈的文字問答系統(tǒng)。圖靈這個(gè)做的也是非常好用的,
直接把我們的問題文字寫到url里面打開鏈接,就可以返回答案了。
[C#] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#region 將文字轉(zhuǎn)出得到回答答案
private string url = "http://www./openapi/api?key=d91b25b8866fef13f82cd28c0d523c8a&info=";
private string QuestionUrl= "http://www./openapi/api?key=d91b25b8866fef13f82cd28c0d523c8a&info=";
public string msg = "";
/// <summary>
/// 獲取圖靈返回的答案
/// </summary>
/// <param name="msg">提問的問題</param>
public void GetAnswer(string msg)
{
    StartCoroutine(GetTuLingtoken(url + msg));
}
private string TuLingtoken = "";
/// <summary>
/// 圖靈的問答系統(tǒng)
/// </summary>
/// <param name="Question">要問的問題</param>
/// <returns></returns>
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);
        }
    }
}


到這里我們就獲取到我們要回答用戶答案的音頻了,回答的答案特別騷氣。 我相信到這一步很多做類似項(xiàng)目的也有不少人做到了,可就是這里沒辦法做下去了,為什么呢,
因?yàn)橐胾nity把網(wǎng)絡(luò)的音頻下載下來播放是非常麻煩的事情,我至今都沒找到辦法,就算用c#的辦法解決了,可是安卓和ios呢,根本調(diào)用不了,再者就是就算你下載下來了,unity好像沒有提供外部播放音頻的功能,我不知道是我能力不足還是unity的問題,感覺很基本的事情居然沒有解決方案。自我懷疑中。。。。
   你可能要問了,那么有沒有一種辦法能解決這個(gè)多平臺(tái)播放音頻的問題呢? 當(dāng)然有了,我用了FMOD這個(gè)插件,可以直接播放網(wǎng)頁(yè)的在線音頻,
用了一個(gè)插件集成進(jìn)來,最后一步就把網(wǎng)頁(yè)音頻地址傳進(jìn)去,就解決了播放的問題,而且是跨平臺(tái)的,ios ,安卓,pc都能用。
[C#] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
    #region 開始播放文字答案
    //要播放的語音文字
    public string AudioMsg = "";
    private string urlForward = @"http://tsn.baidu.com/text2audio?tex=";
    public string AudioUrl = "";
    public AudioStreamDemo asDemo;
    public void PlayAudio(string content)
    {
        Debug.Log(content);
        AudioUrl = @"http://tsn.baidu.com/text2audio?tex=" + content  + "&lan=zh&cuid=隨便寫的&ctp=1&tok=" + token;//
        string[] arrPunc = { ",", "。", "”", ";", "“", " " };
        for (int i = 0; i < arrPunc.Length; ++i)
        {
            //用空白字符來替換指定的標(biāo)點(diǎn)符號(hào),也就相當(dāng)于刪除掉了標(biāo)點(diǎn)符號(hào)
[i]            AudioUrl = AudioUrl.Replace(arrPunc, "%20");
        
        asDemo.SetUrlContext(AudioUrl);
        asDemo.OnPlay();
    }
    #endregion




就這么點(diǎn)代碼,當(dāng)初找不到方案的時(shí)候頭疼了2個(gè)星期。 好在在不放棄的堅(jiān)持下還是搞定了,中間走了不少?gòu)澛?,好在?MemoryC 大神的幫助下,
也一個(gè)個(gè)解決了,為 MemoryC大神打call
     我把這三步驟已經(jīng)縮減到一個(gè)類里面,方便大家查閱,提一下目前這個(gè)功能的一點(diǎn)短處,就是說完話以后要盡快點(diǎn)結(jié)束,讓語音不浪費(fèi)那么多空間,
增快識(shí)別速度,最快的時(shí)候可以在2秒內(nèi)讀出答案,網(wǎng)速好的話比較好。我測(cè)試在安卓讀的最快,然后是pc,最慢是ios,測(cè)試的機(jī)器是iphone5,
不知道和這個(gè)有沒有關(guān)系。再說點(diǎn)這個(gè)東西的拓展,比如一些項(xiàng)目有一些運(yùn)行了windows系統(tǒng)的機(jī)器人,展廳的一些全息 投影之類的項(xiàng)目,都可以接入這個(gè)功能,
讓項(xiàng)目更有可玩性?;揪褪沁@些,
   和往常一樣,底下提供源碼,這次收費(fèi)貴一些,篩選出幫助用到這個(gè)項(xiàng)目的朋友


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多