離線語音合成使用——科大訊飛or雲知音or百度語音
本片主要講解如果使用科大訊飛和雲知音這兩個離線語音合成功能。
目前語音合成的主要有科大訊飛、百度語音、雲知聲。
一、三大產品功能分析
1.百度語音
百度語音合成只有離線上語音服務(免費),沒有純離線,離線上語音合成,在首次使用語音功能,必須聯網,讓其通過網路獲得百度的授權檔案之後,方可正常使用,之後不聯網也可以正常使用,聯網使用優先使用線上包,不聯網則使用離線包。百度語音合成文件地址:http://ai.baidu.com/docs#/TTS-Android-SDK/top,每天有呼叫次數限制,如下圖:
2.科大訊飛
訊飛語語音合成有線上和離線兩種,線上免費,離線收費,收費標準如下:
線上只有聯網的時候才可以正常使用,離線則無需任何聯網,就可正常使用,如果選擇離線包,體驗版SDk下載後就可以為你生產專用的SDK,SDK的demo中會配置好一切,比如說key這些,都會使用你建應用所給的,無需你手動再進行配置了,簡單易用,但下載下來還得除錯一番方可正常使用。科大訊飛官網:
3.雲知聲
二、三者使用
1.百度語音
如何使用請見文件,文件寫的相當詳細,地址:http://ai.baidu.com/docs#/Begin/top,截圖如下:
包括如何註冊如何使用,都明確標出來了,我只將自己的關於語音合成的程式碼貼出來,如下:
public class BaiDuSpeechUtil { private final String TAG = this.getClass().getSimpleName(); private SpeechSynthesizer mSpeechSynthesizer; private String mSampleDirPath; private static final String SAMPLE_DIR_NAME = "baiduTTS"; //-------以下全是在assets下的檔案,使用離線時必須全部copy到手機中方可使用----start-- private static final String SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female.dat"; private static final String SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male.dat"; private static final String TEXT_MODEL_NAME = "bd_etts_text.dat"; private static final String ENGLISH_SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female_en.dat"; private static final String ENGLISH_SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male_en.dat"; private static final String ENGLISH_TEXT_MODEL_NAME = "bd_etts_text_en.dat"; //--------end------------------------------------------------------------- private static BaiDuSpeechUtil baiDuSpeechUtil = null; public static BaiDuSpeechUtil getInstance(){ if(baiDuSpeechUtil == null) { synchronized (BaiDuSpeechUtil.class) { if(baiDuSpeechUtil == null) { baiDuSpeechUtil = new BaiDuSpeechUtil(); } } } return baiDuSpeechUtil; } /** * 初始化百度語音資源 * @param context */ public void setInitialEnv(Context context) { initialEnv(context); } /** * 初始化百度語音播報相關 * @param context */ public void setInitialTts(Context context, SpeechSynthesizerListener speechSynthesizerListener){ initialTts(context,speechSynthesizerListener); } private void initialEnv(Context context) { // long start_time= System.currentTimeMillis(); if (mSampleDirPath == null) { String sdcardPath = Environment.getExternalStorageDirectory().toString(); mSampleDirPath = sdcardPath + "/" + SAMPLE_DIR_NAME; } makeDir(mSampleDirPath); copyFromAssetsToSdcard(context,false, SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_FEMALE_MODEL_NAME); copyFromAssetsToSdcard(context,false, SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_MALE_MODEL_NAME); copyFromAssetsToSdcard(context,false, TEXT_MODEL_NAME, mSampleDirPath + "/" + TEXT_MODEL_NAME); copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME); copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_SPEECH_MALE_MODEL_NAME); copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME); // Log.d(TAG,"initialEnv cost:"+ (System.currentTimeMillis()-start_time)); } private void makeDir(String dirPath) { File file = new File(dirPath); if (!file.exists()) { file.mkdirs(); } } /** * 將sample工程需要的資原始檔拷貝到SD卡中使用(授權檔案為臨時授權檔案,請註冊正式授權) * 主要是在離線時候用到,只需執行一次即可,這裡寫的不嚴謹,應該去判斷一下離線用的那些檔案,sd卡是否存在,如果不存在,則copy,如果存在則無需在copy,可在子執行緒操作 * @param isCover 是否覆蓋已存在的目標檔案 * @param source * @param dest */ private void copyFromAssetsToSdcard(Context context,boolean isCover, String source, String dest) { File file = new File(dest); if (isCover || (!isCover && !file.exists())) { InputStream is = null; FileOutputStream fos = null; try { is = context.getAssets().open(source); String path = dest; fos = new FileOutputStream(path); byte[] buffer = new byte[1024]; int size = 0; while ((size = is.read(buffer, 0, 1024)) != -1) { fos.write(buffer, 0, size); } fos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } if (fos != null) { try { is.close(); } catch (Exception e) { e.printStackTrace(); } } } } } //此方法可在子執行緒中操作,由於這個初始化過程比較費時,大概在1s左右,看專案需求而定,如果是進入介面就必須播放(伴隨UI改變的)的,在UI執行緒,如無其他特殊要求,放在子執行緒中即可 private void initialTts(Context context,SpeechSynthesizerListener speechSynthesizerListener) { // long start_time= System.currentTimeMillis(); mSpeechSynthesizer = SpeechSynthesizer.getInstance(); mSpeechSynthesizer.setContext(context); mSpeechSynthesizer.setSpeechSynthesizerListener(speechSynthesizerListener); mSpeechSynthesizer.setApiKey(Constant.APP_KEY_BAIDU, Constant.APP_SECRET_BAIDU); mSpeechSynthesizer.setAppId(Constant.APP_ID_BAIDU); // 文字模型檔案路徑 (離線引擎使用) mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, mSampleDirPath + "/" + TEXT_MODEL_NAME); mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, mSampleDirPath + "/" + SPEECH_FEMALE_MODEL_NAME); // 本地授權檔案路徑,如未設定將使用預設路徑.設定臨時授權檔案路徑,LICENCE_FILE_NAME請替換成臨時授權檔案的實際路徑,僅在使用臨時license檔案時需要進行設定,如果在[應用管理]中開通了正式離線授權,不需要設定該引數,建議將該行程式碼刪除(離線引擎) // 如果合成結果出現臨時授權檔案將要到期的提示,說明使用了臨時授權檔案,請刪除臨時授權即可。 // 發音人(線上引擎),可用引數為0,1,2,3。。。(伺服器端會動態增加,各值含義參考文件,以文件說明為準。0--普通女聲,1--普通男聲,2--特別男聲,3--情感男聲。。。) mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0"); // 設定Mix模式的合成策略, //mix模式下,wifi使用線上合成,非wifi使用離線合成) mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI); // if(SystemUtil.isNetWorkConnected(getCurrentActivity())) { // // AuthInfo介面用於測試開發者是否成功申請了線上或者離線授權,如果測試授權成功了,可以刪除AuthInfo部分的程式碼(該介面首次驗證時比較耗時),不會影響正常使用(合成使用時 // AuthInfo authInfo=this.mSpeechSynthesizer.auth(TtsMode.MIX); // // if (authInfo.isSuccess()){ // toPrint("auth success"); // }else{ // String errorMsg=authInfo.getTtsError().getDetailMessage(); // toPrint("auth failed errorMsg=" + errorMsg); // } // } // 初始化tts mSpeechSynthesizer.initTts(TtsMode.MIX); // 載入離線英文資源(提供離線英文合成功能) int result = mSpeechSynthesizer.loadEnglishModel(mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath + mSampleDirPath + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME); // Log.d(TAG,"initialTts cost:"+ (System.currentTimeMillis()-start_time)); } /** * 播報的文字 * @param content */ public void speakText(String content) { try{ if(mSpeechSynthesizer != null) { int result = mSpeechSynthesizer.speak(content); if (result < 0) { Log.d(TAG,"error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 "); } } }catch (Exception e) { e.printStackTrace(); } } /** * 暫停 */ public void pauseSpeechSynthesizer(){ if(mSpeechSynthesizer != null) { mSpeechSynthesizer.pause(); } } /** * 停止播放 */ public void stopSpeechSynthesizer(){ if(mSpeechSynthesizer != null) { mSpeechSynthesizer.stop(); } } /** * 接著停止後的地方播放 */ public void resumeSpeechSynthesizer(){ if(mSpeechSynthesizer != null) { mSpeechSynthesizer.resume(); } } /** * 釋放mSpeechSynthesizer,在使用完之後必須呼叫,確保下個介面使用的時候資源已經釋放掉了,否則下個介面將無法正常播放 */ public void releaseSpeechSynthesizer(){ if(mSpeechSynthesizer != null) { mSpeechSynthesizer.release(); } } public void setSpeechSynthesizerNull(){ if(mSpeechSynthesizer != null) { mSpeechSynthesizer = null; } } public void endSpeechSynthesizer(){ pauseSpeechSynthesizer(); stopSpeechSynthesizer(); releaseSpeechSynthesizer(); setSpeechSynthesizerNull(); } }
如何呼叫:
public class MeasurePromptActivity extends BaseActivity implements SpeechSynthesizerListener { private BaiDuSpeechUtil mBaiDuSpeechUtil; private static final String WARM_PROMPT = "百度語音測試,你好開發者"; @Override protected void setCurrentContentView() { setContentView(R.layout.activity_measure_prompt); } @Override protected void init(Bundle savedInstanceState) { } // 語音初始化及播報 private void startSpeakText() { mBaiDuSpeechUtil = BaiDuSpeechUtil.getInstance(); mBaiDuSpeechUtil.setInitialEnv(getCurrentActivity()); mBaiDuSpeechUtil.setInitialTts(getCurrentActivity(), this); speakText(WARM_PROMPT); } private void speakText(String content) { if (mBaiDuSpeechUtil != null) { mBaiDuSpeechUtil.speakText(content); } } @Override protected void onResume() { super.onResume(); startSpeakText(); } //在離開次頁面時呼叫 private void releaseSpeechSynthesizer() { if (mBaiDuSpeechUtil != null) { mBaiDuSpeechUtil.releaseSpeechSynthesizer(); } } @Override public void onSynthesizeStart(String s) { } @Override public void onSynthesizeDataArrived(String s, byte[] bytes, int i) { } @Override public void onSynthesizeFinish(String s) { } @Override public void onSpeechStart(String s) { } @Override public void onSpeechProgressChanged(String s, int i) { } @Override public void onSpeechFinish(String s) { } @Override public void onError(String s, SpeechError speechError) { } }
以上就是百度語音合成的使用,百度其他使用親自行下載官網提供的sample即可。
2.科大訊飛
科大訊飛線上和離線無非就是配置的問題,這裡我只貼重點程式碼,程式碼都是copy官網提供的sample下的,如下:
/**
* 引數設定
* @return
*/
private void setParam(){
// 清空引數
mTts.setParameter(SpeechConstant.PARAMS, null);
//設定合成
if(mEngineType.equals(SpeechConstant.TYPE_CLOUD))
{
//設定使用雲端引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//設定發音人
mTts.setParameter(SpeechConstant.VOICE_NAME,voicerCloud);
}else {
//設定使用本地引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
//設定發音人資源路徑
mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath());
//設定發音人
mTts.setParameter(SpeechConstant.VOICE_NAME,voicerLocal);
}
//設定合成語速
mTts.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50"));
//設定合成音調
mTts.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50"));
//設定合成音量
mTts.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50"));
//設定播放器音訊流型別
mTts.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3"));
// 設定播放合成音訊打斷音樂播放,預設為true
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
// 設定音訊儲存路徑,儲存音訊格式支援pcm、wav,設定路徑為sd卡請注意WRITE_EXTERNAL_STORAGE許可權
// 注:AUDIO_FORMAT引數語記需要更新版本才能生效
mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/tts.wav");
}
回撥監聽,什麼時候開始,什麼時候停止....這些都有的
* 合成回撥監聽。
*/
private SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
showTip("開始播放");
}
@Override
public void onSpeakPaused() {
showTip("暫停播放");
}
@Override
public void onSpeakResumed() {
showTip("繼續播放");
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
// 合成進度
mPercentForBuffering = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
// 播放進度
mPercentForPlaying = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onCompleted(SpeechError error) {
if (error == null) {
showTip("播放完成");
} else if (error != null) {
showTip(error.getPlainDescription(true));
}
}
@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);
// Log.d(TAG, "session id =" + sid);
// }
}
};
切記在結束當前頁面的時候必須將SpeechSynthesizer mTts 釋放掉if( null != mTts ){
mTts.stopSpeaking();
// 退出時釋放連線
mTts.destroy();
}
注意:使用時切記一定要配置正確,離線資源播報人必須copy到正確的目錄下,libs的so庫根據需要新增,否則可能導致包體積過大,gradle必須配置正確libs的目錄,否則就會找不見so庫了,報常見的java.lang.UnsatisfiedLinkError錯誤,如下圖
3.雲知聲
雲之聲只介紹離線的,程式碼擷取都是官網的sample中的,用法和百度的類似,如下:
public class TTSOfflineActivity extends Activity {
private static boolean TTS_PLAY_FLAGE = false;
private EditText mTTSText;
private TextView mTextViewTip;
private TextView mTextViewStatus;
private Button mTTSPlayBtn;
private SpeechSynthesizer mTTSPlayer;
private final String mFrontendModel= "frontend_model";
// private final String mBackendModel = "backend_lzl";
private final String mBackendModel = "backend_female";
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_offline_tts);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.status_bar_main);
mTTSText = (EditText) findViewById(R.id.textViewResult);
mTextViewStatus = (TextView) findViewById(R.id.textViewStatus);
mTextViewTip = (TextView) findViewById(R.id.textViewTip);
mTTSPlayBtn = (Button) findViewById(R.id.recognizer_btn);
mTTSPlayBtn.setEnabled(false);
mTTSPlayBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
TTSPlay();
}
});
initialEnv();
// 初始化本地TTS播報
initTts();
}
/**
* 初始化本地離線TTS,sample中判斷了是否將assets中的檔案copy到sd卡中了,正式專案無需此操作,直接copy即可,但注意許可權問題,尤其是高版本
*/
private void initTts() {
// 初始化語音合成物件
mTTSPlayer = new SpeechSynthesizer(this, Config.appKey, Config.secret);
// 設定本地合成
mTTSPlayer.setOption(SpeechConstants.TTS_SERVICE_MODE, SpeechConstants.TTS_SERVICE_MODE_LOCAL);
// File _FrontendModelFile = new File(mFrontendModel);
// if (!_FrontendModelFile.exists()) {
// toastMessage("檔案:" + mFrontendModel + "不存在,請將assets下相關檔案拷貝到SD卡指定目錄!");
// }
// File _BackendModelFile = new File(mBackendModel);
// if (!_BackendModelFile.exists()) {
// toastMessage("檔案:" + mBackendModel + "不存在,請將assets下相關檔案拷貝到SD卡指定目錄!");
// }
// 設定前端模型
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_FRONTEND_MODEL_PATH, mDirPath+ "/" + mFrontendModel);
// 設定後端模型
mTTSPlayer.setOption(SpeechConstants.TTS_KEY_BACKEND_MODEL_PATH, mDirPath + "/" + mBackendModel);
// 設定回撥監聽
mTTSPlayer.setTTSListener(new SpeechSynthesizerListener() {
@Override
public void onEvent(int type) {
switch (type) {
case SpeechConstants.TTS_EVENT_INIT:
// 初始化成功回撥
log_i("onInitFinish");
mTTSPlayBtn.setEnabled(true);
break;
case SpeechConstants.TTS_EVENT_SYNTHESIZER_START:
// 開始合成回撥
log_i("beginSynthesizer");
break;
case SpeechConstants.TTS_EVENT_SYNTHESIZER_END:
// 合成結束回撥
log_i("endSynthesizer");
break;
case SpeechConstants.TTS_EVENT_BUFFER_BEGIN:
// 開始快取回撥
log_i("beginBuffer");
break;
case SpeechConstants.TTS_EVENT_BUFFER_READY:
// 快取完畢回撥
log_i("bufferReady");
break;
case SpeechConstants.TTS_EVENT_PLAYING_START:
// 開始播放回調
log_i("onPlayBegin");
break;
case SpeechConstants.TTS_EVENT_PLAYING_END:
// 播放完成回撥
log_i("onPlayEnd");
setTTSButtonReady();
break;
case SpeechConstants.TTS_EVENT_PAUSE:
// 暫停回撥
log_i("pause");
break;
case SpeechConstants.TTS_EVENT_RESUME:
// 恢復回撥
log_i("resume");
break;
case SpeechConstants.TTS_EVENT_STOP:
// 停止回撥
log_i("stop");
break;
case SpeechConstants.TTS_EVENT_RELEASE:
// 釋放資源回撥
log_i("release");
break;
default:
break;
}
}
@Override
public void onError(int type, String errorMSG) {
// 語音合成錯誤回撥
log_i("onError");
toastMessage(errorMSG);
setTTSButtonReady();
}
});
// 初始化合成引擎
mTTSPlayer.init("");
}
private void TTSPlay() {
if (!TTS_PLAY_FLAGE) {
mTTSPlayer.playText(mTTSText.getText().toString());
setTTSButtonStop();
} else {
mTTSPlayer.stop();
setTTSButtonReady();
}
}
private void setTTSButtonStop() {
TTS_PLAY_FLAGE = true;
mTTSPlayBtn.setText(R.string.stop_tts);
}
private void setTTSButtonReady() {
mTTSPlayBtn.setText(R.string.start_tts);
TTS_PLAY_FLAGE = false;
}
protected void setTipText(String tip) {
mTextViewTip.setText(tip);
}
protected void setStatusText(String status) {
mTextViewStatus.setText(getString(R.string.lable_status) + "(" + status + ")");
}
@Override
public void onPause() {
super.onPause();
// 主動停止識別
if (mTTSPlayer != null) {
mTTSPlayer.stop();
}
}
private void log_i(String log) {
Log.i("demo", log);
}
@Override
protected void onDestroy() {
// 主動釋放離線引擎
if (mTTSPlayer != null) {
mTTSPlayer.release(SpeechConstants.TTS_RELEASE_ENGINE, null);
}
super.onDestroy();
}
private void toastMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
/**
* 將assets檔案下的離線資源copy到sd卡,操作同百度的
*
* @param isCover 是否覆蓋已存在的目標檔案
* @param source
* @param dest
*/
private void copyFromAssetsToSdcard(Context context, boolean isCover, String source, String dest) {
File file = new File(dest);
if (isCover || (!isCover && !file.exists())) {
InputStream is = null;
FileOutputStream fos = null;
try {
is = context.getAssets().open(source);
String path = dest;
fos = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int size = 0;
while ((size = is.read(buffer, 0, 1024)) != -1) {
fos.write(buffer, 0, size);
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private void makeDir(String dirPath) {
File file = new File(dirPath);
if (!file.exists()) {
file.mkdirs();
}
}
private String mDirPath = null;
private void initialEnv(){
if(mDirPath == null) {
String sdcardPath = Environment.getExternalStorageDirectory().toString();
mDirPath = sdcardPath + "/unsound/tts/";
}
makeDir(mDirPath);
copyFromAssetsToSdcard(this,false,mFrontendModel,mDirPath +"/" + mFrontendModel);
copyFromAssetsToSdcard(this,false,mBackendModel,mDirPath + "/" + mBackendModel);
}
}
assets下的檔案入下圖所示:
這樣基本就正常使用了,還是主要gradle的配置
總結:三種方案中,百度無離線,離線使用個人覺得訊飛優於雲知音,但奈何價格貴呀;如果是定位網際網路產品的話,百度的還是比較好的,離線上融合使用,主要是免費了,科大訊飛的線上也是不錯的;語音合成播報離線,可能是由於模型訓練問題,對於英文和特殊數字的處理有時候不準確,例如110,分場合使用,有時候讀一百一十,有時候讀一一零,還有離線包對英文的識別不準確,有時候會逐個字母的讀,線上一般不會有問題的,由於大多是網際網路產品,都會聯網的,所以上述問題可以忽略的。
關於上方SDK的使用,個人認為先去研究其demo,先保證下載下來能正常使用,大多數出現最多的問題可能是由於無法正確配置導致的,一般主要有以下兩點:
1.so庫沒放對位置
2.gradle檔案配置錯誤(包括lib/jinLibs的路徑配置,gradle版本等等)
3.AndroidManifest配置錯誤,包括許可權等等
這些問題只要細心點都是可以避免的,如果出現問題仔細閱讀官網的文件,尋找解決方法,如果無法解決可以聯絡其技術幫忙解析
相關推薦
離線語音合成使用——科大訊飛or雲知音or百度語音
本片主要講解如果使用科大訊飛和雲知音這兩個離線語音合成功能。目前語音合成的主要有科大訊飛、百度語音、雲知聲。一、三大產品功能分析1.百度語音百度語音合成只有離線上語音服務(免費),沒有純離線,離線上語音合成,在首次使用語音功能,必須聯網,讓其通過網路獲得百度的授權檔案之後,方
ROS百度語音、科大訊飛參考
百度語音介面:https://blog.csdn.net/u011118482/article/details/55001444科大訊飛:https://www.ncnynl.com/archives/201702/1287.htmlhttps://blog.csdn.net
Cordova外掛(語音識別--科大訊飛)
cordova-plugin-IFlyspeech 科大訊飛的語音聽說讀寫的cordova外掛 最近在做一個hybrid webapp的時候需要用到語音識別的功能,網上找到科大訊飛的語音cordova外掛,因為還沒開始使用這個外掛,先總結一下在配置科大
ios下的語音開發——科大訊飛使用
科大訊飛是國內做的比較好的語音開發sdk,首先在網站上註冊賬號等一系列流程下來之後,獲得id的值 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictio
為什麼百度語音比科大訊飛差了幾條街?
辛辛苦苦,信心滿滿的集成了百度TTS語音合成,結果客戶隨便發了個abcdefghijklmn,分分鐘把百度語音完爆了。 http://ai.baidu.com/tech/speech/tts http://www.xfyun.cn/services/online_tts
C#調用科大訊飛離線語音SDK合成TTS
zha http post ref top 代碼 來源 內容 lib bin目錄下有msc.dll動態庫。c#調用科大訊飛的語音合成,需要引用該文件。 該文件是C語言生成的dll,C#沒辦法直接引用。所有需要用C#重新封裝一個TTS.dll,然後再在C#項目中引用封裝的TT
在C#中使用科大訊飛Web API進行語音合成
.get 接口 style serialize pan python版本 compute serial try 最近工作中需要用到訊飛語音合成接口,網上看了下基本都是Java,PHP,Python版本的,正好補上C# 版本,代碼比較簡單。 首先在訊飛開放平臺上創
有關整合科大訊飛sdk的語音(三)語音合成
有關語音合成的,廢話不說,直接程式碼 @property (nonatomic, strong) IFlySpeechSynthesizer *iFlySpeechSynthesizer;//語音合成 - (void)viewWillAppear:(BOOL)animated
手把手的操作——用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(一)
#用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(一) 本人接的任務,做離線語音識別,用的是科大訊飛的離線識別,java不支援離線了,所以下載了windows的離線包,用JNA進行呼叫。之前用的是jni,但是一直沒有測試通過,本人又不會C++,研究了一個星期終究
科大訊飛語音雲使用經歷
科大訊飛的語音識別是屬於一流的行列,那不多想當然選擇科大訊飛了。 在百度上輸:訊飛語音 就能找到,輸科大訊飛會直接出現官網,那裡面沒有。(ps我第一次就是這樣) 下載後會有三個檔案選擇。 一個是語音+ 帶有語音+APP的。一個是含語音互動介面,一個是不含語音互
手把手的操作——用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(二)
上一篇講到了最難的地方,引數的轉換,這裡單獨寫出來 ** 三、引數的轉換(難點) ** 注:本文是以訊飛提供的C語言例子作為模板改寫,語音來源於檔案 1、先分析提供的例子 本人使用的是VS2010 下載連結連結:https://pan.baidu.com/s/
ubuntu下,在QT中利用科大訊飛語音庫實現語音合成TTS
首先要去科大訊飛語音庫註冊,下載linux下的線上合成TTS的SDK,然後在QT下建立一個基於控制檯的工程,其實建立關於UI的也可以,問題不大,這裡以控制檯工程進行說明。將sample中TTS部分的t
科大訊飛離線語音命令詞識別的使用說明
最近因為專案的需求,需要在無網路的情況下實現語音識別的功能,因為之前線上識別一直用的科大的,所以經理就和我說,你花半天時間簡單熟悉一下,然後出一個Demo,下午有人過來看;因為之前科大線上SR也是別人做的,準確的說我只是瞭解過一點,也寫過相關的blog——百度語音
科大訊飛語音合成,pcm轉wav
import android.media.AudioFormat; import android.media.AudioRecord; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.Fi
科大訊飛超強的合成語音軟體InterPhonic下載
1、理論上來說是版本越高越好,比如現在科大訊飛網站上的InterPhonic 6.0線上演示、ViViVoice2.0 線上演示 語氣就更自然更流暢。 2、文語通2.0是科大訊飛的早期版本,所以讀的聲音肯定是不如InterPhonic 4.0、5.0的。 [中科大訊飛
android 融雲 + 科大訊飛 實現仿微信語音訊息轉換為文字(附DEMO原始碼)
融雲SDK 使用很方便,簡單配置就可以搭建即時通訊功能,配合科大訊飛的語音識別, 即可實現微信中語音訊息轉換為文字的功能 融雲sdk的基本使用就不細說了, 網上很多資料 使用融雲sdk自帶的聊天會話介面,想要在此會話介面上增加語音訊息長按時彈出 “轉換為文
Android 科大訊飛 線上和離線語音聽寫
效果圖: 參考資料 專案裡要用語音聽寫,想到了科大訊飛,參考上面的資料完成了最簡單的線上有UI的語音識別,後面想要改成離線也可以使用。參考下面的文章 下載好語記和離線資源之後,想要改成有UI的RecognizerDialog離線語音聽寫,但是沒
科大訊飛語音合成5.0破解版 安裝方法
安裝方法 第一步:建立安裝目錄 在D盤新建兩個資料夾 A和 B做為軟體的安裝目錄 第二步:安裝執行庫 點選InterPhonic5.0執行庫\Runtime Demo資料夾中的Runtime(Demo)_Chinese (PRC).msi 進行安裝 安裝到 第一步時在D
接入高德 SDK 遇到的問題 01:語音導航中科大訊飛線上語音合成次數限制
需求:採用高德導航SDK實現路線導航,並且實現語音播報導航 問題:高德導航語音合成開發指南中,建議採用的科大訊飛線上語音合成存在次數限制,遠遠達不到生產環境的需求量 解決:採用百度離線上語音識別 Android SDK 一、科大訊飛語音合成使用次數有限
關於科大訊飛語音合成的開發(先寫個本地的,簡單)
1、首先在科大訊飛官網申請應用下載語音合成SDK,在專案中匯入Msc.jar包,別忘了還有armeabi目錄下的檔案。然後建一個語音合成的工具類SpeechUtil_xf,具體程式碼下面貼出來,相信大家看註釋已經很清楚了; package com.chai