【JAVA】使用百度語音識別 Rest API,遇到識別結果顯示亂碼的問題和解決
遇到亂碼問題
在使用百度語音識別 JAVA Rest API 的時候,把應用部署到外部Tomcat,
發現返回的語音識別結果是亂碼,而在IDEA上測試API,返回的結果正常。
百度語音識別 Rest API
處理、上傳檔案,獲取識別結果。過程:
com/baidu/speech/restapi/asrdemo/ AsrMain.java
public static void main(String[] args) throws IOException, DemoException {
AsrMain demo = new AsrMain();
String result = demo.run();
// 列印識別結果result
log.info("識別結束:結果是:");
log.info(result);
}
public String run() throws IOException, DemoException {
...
// 以Json方式上傳檔案,獲取返回的字串
result = runJsonPostMethod(token);
...
return result;
}
// 預設以Json方式上傳檔案
// 注:本文作者新增:傳入了引數 WAV檔案路徑+檔名
private String runJsonPostMethod(String token, String fileName) throws IOException, DemoException {
...
byte[] content = getFileContent(fileName);
String speech = base64Encode(content);
...
// 從HttpURLConnection 獲取返回的字串
String result = ConnUtil.getResponseString(conn);
...
return result;
}
// 將檔案讀取到FileInputStream,作為bytes返回
private byte[] getFileContent(String fileName) throws IOException{
File file = new File(fileName);
if (!file.canRead()) {
log.error("檔案不存在或者不可讀: " + file.getAbsolutePath());
}
try(FileInputStream fileInputStream = new FileInputStream(file)) {
// 將InputStream內的內容全部讀取,作為bytes返回
return ConnUtil.getInputStreamContent(fileInputStream);
} catch (Exception e) {
log.error("讀取檔案到輸入流過程錯誤:" + e.getMessage(), e);
return null;
}
}
com/baidu/speech/restapi/common/ ConnUtil.java:
// 從HttpURLConnection 獲取返回的字串
public static String getResponseString(HttpURLConnection conn) throws IOException {
// 從連線資訊返回的內容
return new String(getResponseBytes(conn));
}
// 從HttpURLConnection 獲取返回的 bytes
public static byte[] getResponseBytes(HttpURLConnection conn) throws IOException, DemoException {
int responseCode = conn.getResponseCode();
InputStream inputStream = conn.getInputStream();
...
byte[] result = getInputStreamContent(inputStream);
return result;
}
// 將InputStream內的內容全部讀取,作為bytes返回
public static byte[] getInputStreamContent(InputStream is) throws IOException {
byte[] b = new byte[1024];
// 定義一個輸出流儲存接收到的資料
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 開始接收資料
int len = 0;
while (true) {
len = is.read(b);
if (len == -1) {
// 資料讀完
break;
}
byteArrayOutputStream.write(b, 0, len);
}
return byteArrayOutputStream.toByteArray();
}
Rest API 的使用
String myApiKey = "myApiKey";
String mySecretKey = "mySecretKey";
String fileName = "D:/test.wav";
// 獲得token: TokenHolder為API的 common 包中的類
TokenHolder holder =
new TokenHolder(myApiKey, mySecretKey, "audio_voice_assistant_get");
holder.resfresh();
String token = holder.getToken();
// 預設以json方式上傳音訊檔案
String result = runJsonPostMethod(token, fileName);
// 解析返回的json字串
JsonParser jsonParser = new JsonParser();
// 將json字串轉化成json物件
JsonObject jsonObject = jsonParser.parse(result).getAsJsonObject();
// 返回結果中的錯誤碼。若錯誤碼為0,則識別成功。
String stringErrorNumber = jsonObject.get("err_no").getAsString();
// 返回結果中的語音識別文欄位落
String stringErrorMessage = jsonObject.get("err_msg").getAsString();
int errorNumber;
if(stringErrorNumber != null) {
errorNumber = Integer.valueOf(stringErrorNumber);
} else {
errorNumber = 0;
}
// 根據錯誤碼,進行簡單分類
switch (errorNumber) {
case 0: // 識別成功
log.info("識別結束,結果是:" + jsonObject.get("result").getAsString());
break;
case 3307: // recognition error 識別出錯,無法識別
// TO-DO
break;
case 3308: // speech too long 音訊檔案時長過
// TO-DO
break;
default: // 識別不成功
log.error("百度ASR結果錯誤:" + wavFullName
+ ",錯誤程式碼:" + errorNumber
+ ",錯誤資訊:" + stringErrorMessage);
}
亂碼現象和解決過程
1. 亂碼現象
用1個時長不到60s的,符合百度短語音識別 REST API 格式的,WAV檔案,用IDEA測試,結果:
可見,result 裡邊顯示的是正常的中文識別結果。
打包應用,部署到外部Tomcat,執行測試,也識別成功,日誌顯示卻是亂碼:
2. 解決過程
嘗試修改Tomcat編碼,改 UTF-8,或者改GBK,都無效;
解決各種tomcat中文亂碼問題
修復tomcat9.0中文亂碼問題
tomcat配置及中文亂碼問題的解決方案
在JAVA程式碼中,用 String(str.getBytes(“GBK”), “UTF-8”); 也無效:
知乎:java中GBK編碼格式轉成UTF8,用一段方法實現怎麼做?
public static String recover(String str) throws Throwable {
return new String(str.getBytes("GBK"), "UTF-8");
}
使用後,依舊亂碼:
String jsonBack = new String(jsonBack.getBytes("GBK"), StandardCharsets.UTF_8);
log.info("ASR結果: " + jsonBack);
然後,某天在網上看到這兩個圖:
搜了一下,發現相關文章:
[轉載]字元亂碼說明
看上去,本文遇上的是第一種情況:以GBK方式讀取UTF-8編碼的中文,百度API返回的結果就是UTF-8格式,這應該不用懷疑的,在IDEA內部Tomcat的UTF-8環境下測試都顯示正常。但嘗試過修改了外部Tomcat的編碼,沒用。乾脆從JAVA程式碼切入,看看能不能修改一點程式碼就能解決。
在獲取識別的返回結果中,尋找能夠設定字串String編碼格式的地方。從最底層的
getResponseBytes(HttpURLConnection conn) 和 getInputStreamContent(InputStream is) 看起,兩個函式中沒發現字串String。
繼續往上,發現 getResponseString(HttpURLConnection conn) 裡邊有 new String:
// 從HttpURLConnection 獲取返回的字串
public static String getResponseString(HttpURLConnection conn) throws IOException {
// 從連線資訊返回的內容
return new String(getResponseBytes(conn));
}
於是,直接嘗試加入UTF-8編碼格式:
public static String getResponseString(HttpURLConnection conn) throws IOException {
// 從連線資訊返回的內容,先用UTF-8解碼
return new String(getResponseBytes(conn), StandardCharsets.UTF_8);
}
部署到外部Tomcat測試,結果顯示正常!!!
相關文章
- Python 百度語音識別與合成REST API及ffmpeg使用PythonRESTAPI
- 百度API---語音識別API
- python使用百度語音識別API注意事項PythonAPI
- 深度學習也解決不掉語音識別問題深度學習
- 百度語音識別cordova外掛
- 安裝百度語音識別sdk
- 語音識別技術面臨的問題 (轉)
- JavaScript的語音識別JavaScript
- 用python呼叫百度語音識別api批量處理本地語音檔案PythonAPI
- ASR-使用whisper語音識別
- 語音識別技術
- [譯] 使用 WFST 進行語音識別
- 解決CentOS 中顯示亂碼問題CentOS
- Java基於百度API的圖片文字識別JavaAPI
- 語音識別----音高的處理
- 語音識別方向的資料
- secureCRT顯示亂碼問題Securecrt
- HPUX下,解決xmanager的顯示亂碼問題UX
- LiveCharts中文顯示亂碼問題的解決Echarts
- 西湖大學李子青:人臉識別的挑戰問題和解決技術
- 解決 plsql 遇到亂碼的問題SQL
- PocketSphinx語音識別系統的安裝和使用
- 解決Xmanager連線HPUX顯示亂碼的問題UX
- ubuntu 中文顯示亂碼問題Ubuntu
- PHP顯示MySQL亂碼問題PHPMySql
- win10 無法識別顯示器怎麼辦 win10無法識別顯示器解決方法Win10
- 人工智慧 (08) 語音識別人工智慧
- Swift-語音識別、翻譯Swift
- 語音識別開源專案
- LINUX SSH顯示中文亂碼問題解決Linux
- API智慧識別平臺,API介面自動識別API
- Oracle資料庫PL/SQL Developer查詢結果顯示問號亂碼的解決方法Oracle資料庫SQLDeveloper
- number型別的顯示問題型別
- 語音識別中使用Cool Edit Pro的使用注意事項
- 谷歌開放語音識別API 釋出機器學習雲平臺谷歌API機器學習
- 設定SecureCRT配色和解決亂碼問題Securecrt
- java 百度人臉識別 介面程式碼Java
- Linux的語音識別軟體(轉)Linux