續《是時候開始用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系列其他推薦
