生活随笔
收集整理的這篇文章主要介紹了
发送语音+讯飞翻译 项目案例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構
public LongSparseArray<RecordBean> recordList=new LongSparseArray<>();封裝所有相關數據的Bean
public class RecordBean { public static final String VOICE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "voice"; public static final String XF_VOICE_FILE_PATH = VOICE_PATH + File.separator + "xf_temp_file.wav"; public String pcmPath; public String aacPath; public boolean startRecordSuccess = false;//開始錄音成功,即調用JJMediaSDK.startRecord的返回值 public boolean endRecordSuccess = false;//結束錄音成功,即調用JJMediaSDK.stopRecord的返回值 public long startTime;//開始錄音時間 public long endTime;//結束錄音時間 public boolean sendVoiceSuccess = false;//上傳并發送成功 public boolean translateSuccess = false;//翻譯成功 public String qnKey;//上傳到七牛的語音地址 public long clientid;//當上傳七牛成功后發送一條socket語音消息,此消息需要客戶端生成一個clientid。同時這也是集合recordList中的key public int msgid;//當上傳七牛成功后發送一條socket語音消息,服務器響應時會返回一個msgid,以后就需根據msgid發送及獲取語音對應的文本 public String content;//訊飛翻譯出的內容 public RecordBean(long time) { clientid = time; String data = new SimpleDateFormat("yyyy_MM_dd HH_mm_ss SSS", Locale.getDefault()).format(new Date(time)); this.aacPath = VOICE_PATH + File.separator + "aac_" + data + ".aac"; this.pcmPath = VOICE_PATH + File.separator + "pcm_" + data + ".pcm"; L.i("語音文件保存路徑:" + pcmPath + "\n" + aacPath); } public static class VoiceBean {//發送的語音消息的內容。僅僅包含語音URL路徑以及語音時長 String path; int duration; public VoiceBean(String path, int duration) { this.path = path; this.duration = duration; } }}長按錄制語音相關邏輯
//長按說話mChatInputWidget.setPressListener(new PressListener() { private long key;//集合recordList中的key,同時也是RecordBean中的clientid,同時也是語音消息的clientid @Override public void pressing() { if (micOnoff == 1) {//是否正在上麥(占用錄音設備):0,未指定;1,開;2,關 ToastHelper.showToastInThread("親,發送語音功能需要下麥哦..."); } else { //注意,以下代碼要在具有錄音權限時訪問 AudioManager audioManager = (AudioManager) ChatActivity.this.getSystemService(Context.AUDIO_SERVICE); audioManager.setMicrophoneMute(false);//關閉麥克風靜音 //鍵為當前時間,以保證唯一性 key = System.currentTimeMillis(); RecordBean recordBean = new RecordBean(key); recordList.put(key, recordBean); //調用JNI代碼啟動錄音,錄音成功后會生成兩個文件,這兩個文件的存放位置封裝在了recordBean中 JJMediaSDK.captureStop();//停止錄音 recordBean.startRecordSuccess = JJMediaSDK.startRecord(recordBean.pcmPath, recordBean.aacPath); recordBean.startTime = System.currentTimeMillis();//記錄開始和結束錄音時間,以獲取錄音時長 if (!recordBean.startRecordSuccess) Toast.makeText(ChatActivity.this, "錄音失敗", Toast.LENGTH_SHORT).show(); else pressSpeeking("正在說話...");//一個自定義的UI,當按住的時候一直顯示,當松開的時候消失 } } @Override public void pressStop() { RecordBean recordBean = recordList.get(key);//獲取當前key對應的RecordBean if (recordBean == null || !recordBean.startRecordSuccess) {//肯定是錄音失敗了 Toast.makeText(ChatActivity.this, "錄音失敗", Toast.LENGTH_SHORT).show(); return; } AudioManager audioManager = (AudioManager) ChatActivity.this.getSystemService(Context.AUDIO_SERVICE); audioManager.setMicrophoneMute(true);//開啟麥克風靜音 //調用JNI代碼結束錄音。JNI同事說這里不會失敗的。誰信啊,萬一存儲空間不足或手機突然爆掉了呢? recordBean.endRecordSuccess = JJMediaSDK.stopRecord(); recordBean.endTime = System.currentTimeMillis(); pressSpeekingdimiss(); if (!recordBean.endRecordSuccess) { Toast.makeText(ChatActivity.this, "錄音失敗", Toast.LENGTH_SHORT).show(); return; } //****************************************【第一個異步:異步上傳語音】***************************************** //異步上傳語音到七牛,當上傳成功后發送一條socket消息通知語音的URL路徑,此時其他用戶就可以播放此語音了 //同時,服務器收到此消息后會做出響應,主要是返回一個msgid,以后就可以根據msgid通知及獲取語音對應的文本了 VoiceUtils.uploadVoiceAndSendMsg(ChatActivity.this, recordBean); //****************************************【第二個異步:異步訊飛翻譯】***************************************** if (mIat == null) mIat = VoiceUtils.getSpeechRecognizerInstance(ChatActivity.this);//訊飛SDK初始化 if (mIat == null) return;//訊飛SDK初始化失敗 //訊飛SDK翻譯過程及狀態監聽 RecognizerListener recognizerListener = VoiceUtils.getRecognizerListener(content -> {//翻譯成功回調 recordBean.content = content; recordBean.translateSuccess = true; Toast.makeText(ChatActivity.this, recordBean.content, Toast.LENGTH_SHORT).show(); //**************************【將上傳到七牛的語音和訊飛翻譯的內容關聯起來】****************************** //如果第一個異步已經完成,則直接發一條socket消息,將兩者內容聯系在一起;否則等第一個異步完成以后再做處理 if (recordBean.sendVoiceSuccess) SendMsgUtils.sendVoiceContentMsg(ChatActivity.this, recordBean); }); // 函數調用返回值 int ret = mIat.startListening(recognizerListener); if (ret != ErrorCode.SUCCESS) { Toast.makeText(ChatActivity.this, "翻譯失敗", Toast.LENGTH_SHORT).show(); L.i("訊飛SDK翻譯失敗,錯誤碼:" + ret); } else { byte[] audioData = VoiceUtils.readSDFile(recordBean.pcmPath);//讀取SDK返回的pcm文件流 if (null != audioData) { L.i("訊飛SDK開始音頻流識別"); mIat.writeAudio(audioData, 0, audioData.length); mIat.stopListening(); } else { mIat.cancel(); Toast.makeText(ChatActivity.this, "訊飛SDK讀取音頻流失敗", Toast.LENGTH_SHORT).show(); } } }});發送三條消息
public class SendMsgUtils { /** * 發送語音、Gif圖等通用聊天消息 * * @param activity 必須是ChatActivity或ChatActivityPrivate * @param msgType 例如Common.e_MsgType.MSGTYPE_GIF_VALUE * @param content 消息內容,一般都是json格式 */ public static void sendNormalMsg(Activity activity, int msgType, String content, long clientid) { if (activity instanceof ChatActivity) { if (msgType == Common.e_MsgType.MSGTYPE_VOICE_VALUE || msgType == Common.e_MsgType.MSGTYPE_GIF_VALUE) { int roleType = ((ChatActivity) activity).getRoleType(); if (roleType <= 0) {//游客 Toast.makeText(activity, "您沒有權限發送此類型消息", Toast.LENGTH_SHORT).show(); return; } } } int groupId = 0; boolean isGroup = false; int dstId = 0; if (activity instanceof ChatActivity) { groupId = ((ChatActivity) activity).getGroupId(); isGroup = ((ChatActivity) activity).isGroup(); dstId = ((ChatActivity) activity).getDstId(); } else if (activity instanceof ChatActivityPrivate) { groupId = ((ChatActivityPrivate) activity).getGroupId(); isGroup = ((ChatActivityPrivate) activity).isGroup(); dstId = ((ChatActivityPrivate) activity).getDstId(); } ChatReqHelper.sendNormalMsg(content, groupId, isGroup, dstId, clientid); ChatModel model = new ChatModel(content, ChatModel.RIGHT, msgType); model.clientid = clientid; model.setMsgTime((int) (System.currentTimeMillis() / 1000)); model.setGroupId(groupId); model.setSrcUser(ChatReqHelper.getUserInfo()); if (activity instanceof ChatActivity) { ((ChatActivity) activity).getmGroupChats().add(0, model); ((ChatActivity) activity).getmRvSquareChat().getAdapter().notifyItemInserted(0); ((ChatActivity) activity).getmRvSquareChat().scrollToPosition(0); } else if (activity instanceof ChatActivityPrivate) { Common.UserInfo_t dstUserInfo = Common.UserInfo_t.getDefaultInstance().newBuilderForType().setUserId(dstId).build(); model.setDstUser(dstUserInfo); ((ChatActivityPrivate) activity).getmGroupChats().add(0, model); ((ChatActivityPrivate) activity).getmRvSquareChat().getAdapter().notifyItemInserted(0); ((ChatActivityPrivate) activity).getmRvSquareChat().scrollToPosition(0); } } /** * 發送語音消息(里面只有語音的URL路徑及時長),里面用的完全就是sendNormalMsg的邏輯 * * @param activity 必須是ChatActivity或ChatActivityPrivate * @param recordBean 封裝所有信息的bean */ public static void sendNormalVoiceMsg(Activity activity, RecordBean recordBean) { //當上傳七牛成功后發送一條socket消息,當收到響應時(會返回一個msgid)說明此socket消息發送成功了 int duration = (int) ((recordBean.endTime - recordBean.startTime) / 1000); RecordBean.VoiceBean voiceBean = new RecordBean.VoiceBean(recordBean.qnKey, duration); String content = new Gson().toJson(voiceBean);//{"path:":"", duration:100} sendNormalMsg(activity, Common.e_MsgType.MSGTYPE_VOICE_VALUE, content, recordBean.clientid); L.i("發送語音消息。content=" + content + "。clientid=" + recordBean.clientid); } /** * 發送語音所對應的文本消息,目的是將上傳到七牛的【語音】和訊飛翻譯的【內容】關聯起來 */ public static void sendVoiceContentMsg(Activity activity, RecordBean recordBean) { if (recordBean == null) return; if (recordBean.sendVoiceSuccess && recordBean.translateSuccess && recordBean.msgid != 0) { int groupId = 0, dstId = 0; if (activity instanceof ChatActivity) { groupId = ((ChatActivity) activity).getGroupId(); dstId = ((ChatActivity) activity).getDstId(); } else if (activity instanceof ChatActivityPrivate) { groupId = ((ChatActivityPrivate) activity).getGroupId(); dstId = ((ChatActivityPrivate) activity).getDstId(); } ChatSvr.CMDVoiceContentSubmit message = ChatSvr.CMDVoiceContentSubmit.newBuilder() .setGroupid(groupId)//群id .setSrcuid(AccountManager.getInstance().getServiceUserId())//消息發起者id .setDstuid(dstId)//消息接收者id(群聊傳0) .setMsgid(recordBean.msgid)//msgid,此msgid是由服務器返回的 .setContent(recordBean.content)//語音消息翻譯成文本的內容 .build(); LoginConnection.voiceContentSubmit(message.toByteArray(), null); L.i("發送語音文本消息。content=" + recordBean.content + "。msgid=" + recordBean.msgid); if (recordBean.pcmPath != null && new File(recordBean.pcmPath).delete()) L.i("成功刪除pcm臨時文件"); if (recordBean.aacPath != null && new File(recordBean.aacPath).delete()) L.i("成功刪除aac臨時文件"); //移除集合中的此RecordBean LongSparseArray<RecordBean> recordList = null; if (activity instanceof ChatActivity) recordList = ((ChatActivity) activity).recordList; else if (activity instanceof ChatActivityPrivate) recordList = ((ChatActivityPrivate) activity).recordList; if (recordList != null) { recordList.remove(recordBean.clientid); L.i("成功移除recordBean:" + recordBean.clientid); } } else L.i("RecordBean狀態錯誤" + recordBean.toString()); } /** * 查詢語音文本消息。這時已經與RecordBeanme沒有任何關系了,這里的msgid是后臺返回的 */ public static void qryVoiceContentMsg(Activity activity, int msgid) { int groupId = 0, dstId = 0; if (activity instanceof ChatActivity) { groupId = ((ChatActivity) activity).getGroupId(); dstId = ((ChatActivity) activity).getDstId(); } else if (activity instanceof ChatActivityPrivate) { groupId = ((ChatActivityPrivate) activity).getGroupId(); dstId = ((ChatActivityPrivate) activity).getDstId(); } ChatSvr.CMDQryChatMsgReq req = ChatSvr.CMDQryChatMsgReq.newBuilder() .setGroupid(groupId)//群id .setSrcuid(AccountManager.getInstance().getServiceUserId())//消息發起者id .setDstuid(dstId)//消息接收者id(群聊傳0) .setMsgid(msgid)//msgid .build(); LoginConnection.qryChatMsgReq(req.toByteArray(), null); L.i("查詢語音文本消息。msgid=" + msgid + "。groupId=" + groupId); }}服務器的兩個響應
public void onEventMainThread(BaseEvent event) { if (event.getEvent() == EventHelper.EVENT_GROUPMSGRECV) { if (event.getData() instanceof ChatSvr.CMDGroupMsgRecv) { //異步上傳語音到七牛成功后,客戶端發送一條socket消息通知語音的URL路徑 //這是當服務器收到此消息后做出的響應,我們主要是拿到回一個msgid,以后就可以根據msgid通知語音對應的文本了 ChatSvr.CMDGroupMsgRecv msgRecv = (ChatSvr.CMDGroupMsgRecv) event.getData(); for (int i = 0; i < recordList.size(); i++) { Long key = recordList.keyAt(i); if (msgRecv.getClientMSgId() == key) {//RecordBean的clientid和recordList的key時同一個數 RecordBean recordBean = recordList.get(key); recordBean.sendVoiceSuccess = true; recordBean.msgid = msgRecv.getMsgId(); L.i("發送語音響應:msgid=" + recordBean.msgid + " clientid=" + recordBean.clientid); //**************************【將上傳到七牛的語音和訊飛翻譯的內容關聯起來】****************************** //如果第二個異步已經完成,則直接發一條socket消息,將兩者內容聯系在一起;否則等第二個異步完成以后再做處理 if (recordBean.translateSuccess) SendMsgUtils.sendVoiceContentMsg(this, recordBean); break; } } } return; } if (event.getEvent() == EventHelper.EVENT_QRY_CHAT_MSG) { //**********************************************【響應查詢語音消息】************************************************ if (event.getData() instanceof ChatSvr.CMDQryChatMsgResp) { ChatSvr.CMDQryChatMsgResp resp = (ChatSvr.CMDQryChatMsgResp) event.getData(); if (resp.getMsg() != null) { int msgID = resp.getMsg().getMsgId(); String voiceContent; if (resp.getMsg().getVoiceContent() != null) voiceContent = resp.getMsg().getVoiceContent().getData(); else voiceContent = "翻譯失敗"; Toast.makeText(this, "msgID:" + msgID + " 內容:" + voiceContent, Toast.LENGTH_SHORT).show(); L.i("查詢語音文本響應。" + "msgID:" + msgID + " 內容:" + voiceContent); } } return; }}訊飛監聽、上傳語音等
public class VoiceUtils { public interface OnRecognizerResultListener { void onResult(String content); } public static RecognizerListener getRecognizerListener(OnRecognizerResultListener listener) { return new RecognizerListener() { StringBuilder sb = new StringBuilder(); @Override public void onBeginOfSpeech() {// 此回調表示:sdk內部錄音機已經準備好了,用戶可以開始語音輸入 L.i("onBeginOfSpeech"); } @Override public void onError(SpeechError error) { L.i("onError:" + error.getErrorCode() + " " + error.getErrorDescription()); //http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=13056&fromuid=44990 // 錯誤碼:10118(您沒有說話),可能是錄音機權限被禁,需要提示用戶打開應用的錄音權限。 // 如果使用本地功能(語記)需要提示用戶開啟語記的錄音權限。 //沒有數據,vad_bos設置問題 } @Override public void onEndOfSpeech() {// 此回調表示:檢測到了語音的尾端點,已經進入識別過程,不再接受語音輸入 L.i("onEndOfSpeech"); } @Override public void onResult(RecognizerResult results, boolean isLast) { L.i("onResult:" + results.getResultString() + "。格式化內容:" + getFormatResult(results) + "。isLast:" + isLast); sb.append(getFormatResult(results)); if (isLast) { L.i("完整結果為:" + sb.toString()); listener.onResult(sb.toString()); } } @Override public void onVolumeChanged(int volume, byte[] data) { L.i("onVolumeChanged。當前正在說話,音量大小:" + volume + "。返回音頻數據長度:" + data.length); } @Override public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { // 以下代碼用于獲取與云端的會話id,當業務出錯時將會話id提供給技術支持人員,可用于查詢會話日志,定位出錯原因 // 若使用本地能力,會話id為null if (SpeechEvent.EVENT_SESSION_ID == eventType) { String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID); L.i("onEvent:" + eventType + " session_id =" + sid); } } }; } public static SpeechRecognizer getSpeechRecognizerInstance(Context context) { //*****************************************************初始化監聽器************************************************ InitListener mInitListener = code -> { if (code != ErrorCode.SUCCESS) L.i("初始化失敗,錯誤碼:" + code); }; SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(context, mInitListener); if (null == mIat) { // 創建單例失敗,與 21001 錯誤為同樣原因,參考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688 L.i("創建對象失敗,請確認 libmsc.so 放置正確,且有調用 createUtility 進行初始化"); Toast.makeText(context, "語音引擎初始化失敗", Toast.LENGTH_SHORT).show(); return null; } //******************************************************參數設置************************************************** // 清空參數 mIat.setParameter(SpeechConstant.PARAMS, null); mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);// 設置聽寫引擎 mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");// 設置返回結果格式 mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");// 設置語言 mIat.setParameter(SpeechConstant.ACCENT, "mandarin");// 設置語言區域,mandarin為普通話; // 設置語音前端點:靜音超時時間,即用戶多長時間不說話則當做超時處理 mIat.setParameter(SpeechConstant.VAD_BOS, "4000");//4000 // 設置語音后端點:后端點靜音檢測時間,即用戶停止說話多長時間內即認為不再輸入, 自動停止錄音 mIat.setParameter(SpeechConstant.VAD_EOS, "4000");//1000 // 設置標點符號,設置為"0"返回結果無標點,設置為"1"返回結果有標點 mIat.setParameter(SpeechConstant.ASR_PTT, "1"); // 設置音頻【保存】路徑,保存音頻格式支持pcm、wav,設置路徑為sd卡請注意WRITE_EXTERNAL_STORAGE權限 mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");// 注:AUDIO_FORMAT參數語記需要更新版本才能生效 mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, RecordBean.XF_VOICE_FILE_PATH); // 設置音頻來源為外部文件 mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-1"); // 也可以像以下這樣直接設置音頻文件路徑識別(要求設置文件在sdcard上的全路徑): //mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2"); //mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, "sdcard/XXX/XXX.pcm"); return mIat; } /** * 獲取解析出的字符串內容 */ private static String getFormatResult(RecognizerResult results) { String text = parseIatResult(results.getResultString()); String sn = null; // 讀取json結果中的sn字段 try { JSONObject resultJson = new JSONObject(results.getResultString()); sn = resultJson.optString("sn"); } catch (JSONException e) { e.printStackTrace(); } // 用HashMap存儲聽寫結果 HashMap<String, String> mIatResults = new LinkedHashMap<>(); mIatResults.put(sn, text); StringBuilder resultBuffer = new StringBuilder(); for (String key : mIatResults.keySet()) { resultBuffer.append(mIatResults.get(key)); } return resultBuffer.toString(); } private static String parseIatResult(String json) { StringBuilder ret = new StringBuilder(); try { JSONArray words = new JSONObject(new JSONTokener(json)).getJSONArray("ws"); for (int i = 0; i < words.length(); i++) { // 轉寫結果詞,默認使用第一個結果 JSONArray items = words.getJSONObject(i).getJSONArray("cw"); JSONObject obj = items.getJSONObject(0); ret.append(obj.getString("w")); } } catch (Exception e) { e.printStackTrace(); } return ret.toString(); } /** * 上傳語音消息,然后發送語音消息 */ public static void uploadVoiceAndSendMsg(BaseActivity activity, RecordBean recordBean) { if (recordBean == null || recordBean.aacPath == null) return; final File file = new File(recordBean.aacPath); if (!file.exists()) { ToastHelper.showErrorToast("錄音文件不存在"); return; } if (AccountManager.getInstance().getServiceInfo() == null) { ToastHelper.showToastInThread("您尚未登錄"); return; } activity.showLoadingDialog(); //**************************************************上傳語音消息**************************************** String keyQN = LoginConnection.getUploadKey(recordBean.aacPath); HBApplication.getInstance().getUploadManager() .put(recordBean.aacPath, keyQN, LoginConnection.getUploadToken(), (key, info, res) -> { L.i("上傳語音騎牛key:" + key); //*************************************發送語音消息***************************************** //當上傳七牛成功后發送一條socket消息,當收到響應時(會返回一個msgid)說明此socket消息發送成功了 recordBean.qnKey = key; SendMsgUtils.sendNormalVoiceMsg(activity, recordBean); }, new UploadOptions(null, null, false, (key, percent) -> { //if (activity.dialog != null) activity.dialog.update((int) percent * 100); }, null)); } /** * 【讀】SD卡也即/mnt/sdcard/目錄下的文件 */ public static byte[] readSDFile(String fileName) { if (TextUtils.isEmpty(fileName)) return null; File file = new File(fileName); if (!file.exists()) return null; try { InputStream ins = new FileInputStream(file); byte[] data = new byte[ins.available()]; ins.read(data); ins.close(); return data; } catch (Exception e) { e.printStackTrace(); } return null; }}日志
發送語音
I/RecordBean: 包青天bqt(RecordBean.java:39)#<init>【語音文件保存路徑:/storage/emulated/0/voice/pcm_2017_07_04 17_05_23 100.pcm /storage/emulated/0/voice/aac_2017_07_04 17_05_23 100.aac】I/ChatActivity$5: 包青天bqt(ChatActivity.java:908)#pressStop【訊飛SDK開始音頻流識別】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:97)#onVolumeChanged【onVolumeChanged。當前正在說話,音量大小:0。返回音頻數據長度:33280】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:81)#onEndOfSpeech【onEndOfSpeech】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:106)#onEvent【onEvent:20001 session_id =iatad118bff@gz02600cb6a6553cf300】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:86)#onResult【onResult:{"sn":1,"ls":false,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"sc":0.00,"w":"你好"}]}]}。格式化內容:你好。isLast:false】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:106)#onEvent【onEvent:20001 session_id =iatad118bff@gz02600cb6a6553cf300】I/VoiceUtils: 包青天bqt(VoiceUtils.java:222)#lambda$uploadVoiceAndSendMsg$1【上傳語音騎牛key:_F-UBAN-YeQIB.aac】I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:87)#sendNormalVoiceMsg【發送語音消息。content={"duration":1,"path":"_F-UBAN-YeQIB.aac"}。clientid=1499159123100】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:86)#onResult【onResult:{"sn":2,"ls":true,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"sc":0.00,"w":"。"}]}]}。格式化內容:。。isLast:true】I/VoiceUtils$1: 包青天bqt(VoiceUtils.java:89)#onResult【完整結果為:你好。】I/ChatActivity: 包青天bqt(ChatActivity.java:1703)#onEventMainThread【發送語音響應:msgid=13878 clientid=1499159123100】I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:113)#sendVoiceContentMsg【發送語音文本消息。content=你好。。msgid=13878】I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:115)#sendVoiceContentMsg【成功刪除pcm臨時文件】I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:116)#sendVoiceContentMsg【成功刪除aac臨時文件】I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:124)#sendVoiceContentMsg【成功移除recordBean:1499159123100】查詢語音對應文字I/SendMsgUtils: 包青天bqt(SendMsgUtils.java:148)#qryVoiceContentMsg【查詢語音文本消息。msgid=13879。groupId=36】I/ChatActivity: 包青天bqt(ChatActivity.java:1723)#onEventMainThread【查詢語音文本響應。msgID:13879 內容:需要。】2017-7-4
總結
以上是生活随笔為你收集整理的发送语音+讯飞翻译 项目案例的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。