續《是時候開始用C#快速開發移動應用了》刷屏之後,把C#開發移動應用的技術 => Xamarin,在這裡和大家做一個分享!
語音合成:也被稱為文字轉換技術(TTS),它是將計算機自己產生的、或外部輸入的文字資訊轉變為可以聽得懂的、流利的口語輸出的技術。
技術選型:語音合成初步選擇有兩個,一是訊飛、二是百度。
因為使用的是Xamarin開發在對接訊飛的時候android繫結上有些問題,攻克不了,訊飛對於Xamarin的態度也是觀望,可能是因為國內使用Xamarin的比較少。先來說說訊飛和百度語音各自的優缺點:
1.訊飛支援的位元組數更多8xxx位元組,具體的值忘記了,反正4k的漢字不成問題;百度支援的位元組數是1024個位元組。
2.訊飛sdk比較小,對接百度的sdk比較大,因為百度語音的離線線上sdk在一個裡面,大概有10幾兆所以,為了避免安裝包過大,所有隻能使用百度的REST方式了。
3.訊飛語音sdk在Xamarin.Android繫結上有問題,暫時沒有攻破,在Xamarin.Ios上打除錯版也有問題,設定成Release上勉強可以使用。
綜合上面的原因,所以選擇了百度的REST作為對接語音合成的技術實現。
呼叫流程:1.獲取語音合成密碼access_token;2.帶上祕鑰和文字請求api返回資料流檔案;
核心流程方案
步驟一:獲取access_token
請求地址:
引數說明:
- grant_type:必須引數,固定為“client_credentials”;
- client_id:必須引數,應用的 API Key;
- client_secret:必須引數,應用的 Secret Key;
返回結果:
{
"access_token": "24.6a0d0ee7cc62446cf0a5fbc9d6204321.2592000.1498802594.282335-9044454",
"session_key": "9mzdDZfH3RYNxaNq9Kb6RP5JqsthOmat9g4guVLvbm2YymOWPxDiq3vQvdjZrByadZp4qou9F4wYH2dfptIjxdPwzmKH",
"scope": "public audio_tts_post wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian wangrantest_test wangrantest_test1 bnstest_test1 bnstest_test2 vis-classify_flower",
"refresh_token": "25.df4ee25f807fe4fc8d0e025dc7b8549e.315360000.1811570594.282335-9044454",
"session_secret": "237af35e4de40ce40e74951d5e187a18",
"expires_in": 2592000
}
注意:access_token有效期30天。
步驟二:合成音訊
請求地址:
注意:引數都需要經過兩次 URLENCODE 操作。如果是直接在瀏覽器位址列輸入則不需要。
返回結果:
如果合成成功,下行資料為二進位制語音檔案,具體header資訊 Content-Type:audio/mp3;如果合成出現錯誤,則會返回json結果,具體header資訊為:Content-Type:application/json。其中sn資料主要用於DEBUG追查問題,如果出現問題,可以提供sn幫助確認問題。
錯誤例項為:
{"err_no":500,"err_msg":"notsupport.","sn":"abcdefgh","idx":1}
錯誤碼解釋
錯誤碼 |
含義 |
500 |
不支援輸入 |
501 |
輸入引數不正確 |
502 |
token驗證失敗 |
503 |
合成後端錯誤 |
注意:合成文字長度必須小於1024位元組,如果本文長度較長,可以採用多次請求的方式。切忌不可文字長度超過限制。
更多官方文件請訪問:http://yuyin.baidu.com/docs
Xamarin呼叫核心程式碼如下:
string url = "http://tsn.baidu.com/text2audio"; //百度tts請求地址 HttpClient client = new HttpClient(); client.Timeout = new TimeSpan(0, 1, 0); //超時時間設定 Dictionary<string, string> param = new Dictionary<string, string>() { { "lan", "zh" },{ "ctp", "1" } //不需要修改的引數 }; param.Add("tex", "需要合成的文字內容"); //需要轉換的文字內容 param.Add("cuid", "userid"); //使用者唯一標識 param.Add("tok", "24.6a0d0ee7cc62446cf0a5fbc9d6204321.2592000.1498802594.282335-9044454");//access_token,在傳送之前先呼叫一次獲取到這個值 FormUrlEncodedContent content = new FormUrlEncodedContent(param); //post請求引數設定物件 try { HttpResponseMessage x = await client.PostAsync(url, content); if (x.StatusCode == HttpStatusCode.OK) { Stream st = await x.Content.ReadAsStreamAsync(); //路徑儲存地址,ios和android各不相同,分別實現,傳遞檔名 string filePath = DependencyService.Get<IResourcesHelper>().GetImageDownLoadPath("bd_" + DateTime.Now.Ticks + ".mp3"); using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { st.CopyTo(fileStream); //儲存檔案 } } else { //todo:請求失敗處理邏輯(警告) } } catch { //todo:異常處理邏輯(警告) }
Xamarin系列其他推薦