關於科大訊飛語音合成的開發(先寫個本地的,簡單)
阿新 • • 發佈:2019-01-29
1、首先在科大訊飛官網申請應用下載語音合成SDK,在專案中匯入Msc.jar包,別忘了還有armeabi目錄下的檔案。然後建一個語音合成的工具類SpeechUtil_xf,具體程式碼下面貼出來,相信大家看註釋已經很清楚了;
package com.chainway.nursestation.tool;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
/**
* 科大訊飛的語音合成工具類
* @author wushengjun
* @date 2016年8月23日
*/
public class SpeechUtil_xf {
private String TAG = "SpeechUtil_xf";
private Context context;
private String app_id = "57bbbdf5";
//語音合成物件
private SpeechSynthesizer mSpeechSynthesizer;
// 預設雲端發音人
public static String voicerCloud="xiaoyan";
// 預設本地發音人
public static String voicerLocal="xiaoyan";
// 引擎型別
private String mEngineType = SpeechConstant.TYPE_LOCAL;
private int speed = 50; //合成語音音速
private int pitch = 50; //合成語音音調
private int volume = 100; //合成語音音量,0-100
private int stream_type = 3; //播放器的音訊流型別
private boolean isInterrupt = true; //播放合成音訊打斷音樂播放,預設為true
private String audio_formal = "wav"; //音訊格式,只支援wav和pcm格式
public SpeechUtil_xf(Context context) {
this.context = context;
setAppId(); //一定要在語音合成物件例項化前設定,不然會報21001錯誤(沒有安裝語音元件)
init();
setParams();
}
/**
* 初始化語音合成
*/
private void init() {
mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(context, mInitListener);
}
/**
* 設定語音合成的引數
*/
private void setParams() {
// 清空引數
mSpeechSynthesizer.setParameter(SpeechConstant.PARAMS, null);
//設定合成的模式
//設定使用本地引擎
mSpeechSynthesizer.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
//設定發音人資源路徑
mSpeechSynthesizer.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());
//設定發音人
mSpeechSynthesizer.setParameter(SpeechConstant.VOICE_NAME, voicerLocal);
//設定合成音速
mSpeechSynthesizer.setParameter(SpeechConstant.SPEED, String.valueOf(speed));
//設定合成音調
mSpeechSynthesizer.setParameter(SpeechConstant.PITCH, String.valueOf(pitch));
//設定合成音量
mSpeechSynthesizer.setParameter(SpeechConstant.VOLUME, String.valueOf(volume));
//設定播放器音訊流型別
mSpeechSynthesizer.setParameter(SpeechConstant.STREAM_TYPE, String.valueOf(stream_type));
// 設定播放合成音訊打斷音樂播放,預設為true
mSpeechSynthesizer.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, String.valueOf(isInterrupt));
// 設定合成音訊格式,只支援wav和pcm格式
mSpeechSynthesizer.setParameter(SpeechConstant.AUDIO_FORMAT, audio_formal);
mSpeechSynthesizer.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/xf_yuyin/tts.wav");
}
/**
* 開始合成語音並播放
* @param content 播放內容
* @return 播放結果碼
*/
public int startSpeak(String content) {
// setParams();
int result = mSpeechSynthesizer.startSpeaking(content, mTtsListener);
if(result != ErrorCode.SUCCESS) {
toastMessage("語音合成失敗,錯誤碼: " + result);
}
return result;
}
/**
* 開始合成語音並播放
* @param content 播放內容的資源id
* @return 播放結果碼
*/
public int startSpeak(int resId) {
return startSpeak(context.getString(resId));
}
/**
* 初始化監聽
*/
private InitListener mInitListener = new InitListener() {
@Override
public void onInit(int arg0) {
// TODO Auto-generated method stub
Log.d(TAG, "InitListener init, code=" + arg0);
if(arg0 != ErrorCode.SUCCESS) {
toastMessage("初始化失敗,錯誤碼:" + arg0);
} else {
}
}
};
/**
* 合成回撥監聽。
*/
private SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
//開始播放
}
@Override
public void onSpeakPaused() {
//暫停播放
}
@Override
public void onSpeakResumed() {
//"繼續播放")
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
// 合成進度
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
// 播放進度
}
@Override
public void onCompleted(SpeechError error) {
if (error == null) { //播放完成
} else {
toastMessage("code=" + error.getErrorCode() + ",msg=" + error.getErrorDescription());
}
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
// 以下程式碼用於獲取與雲端的會話id,當業務出錯時將會話id提供給技術支援人員,可用於查詢會話日誌,定位出錯原因
// 若使用本地能力,會話id為null
}
};
/**
* 獲取本地assets資料夾下的發音人資源路徑
*/
private String getResourcePath() {
StringBuffer tempBuffer = new StringBuffer();
//合成通用資源
tempBuffer.append(ResourceUtil.generateResourcePath(context, RESOURCE_TYPE.assets, "tts/common.jet"));
tempBuffer.append(";");
//發音人資源
tempBuffer.append(ResourceUtil.generateResourcePath(context, RESOURCE_TYPE.assets, "tts/"+ voicerLocal +".jet"));
return tempBuffer.toString();
}
/** 應用程式入口處呼叫,避免手機記憶體過小,殺死後臺程序後通過歷史intent進入Activity造成SpeechUtility物件為null
* 注意:此介面在非主程序呼叫會返回null物件,如需在非主程序使用語音功能,請增加引數:SpeechConstant.FORCE_LOGIN+"=true"
* 引數間使用“,”分隔。
* 設定你申請的應用appid
* 注意: appid 必須和下載的SDK保持一致,否則會出現10407錯誤
* 一定要在語音合成物件例項化前設定,不然會報21001錯誤(沒有安裝語音元件)
*/
private void setAppId() {
StringBuffer param = new StringBuffer();
param.append("appid="+app_id);
param.append(",");
// 設定使用v5+
param.append(SpeechConstant.ENGINE_MODE+"="+SpeechConstant.MODE_MSC);
SpeechUtility.createUtility(context, param.toString());
}
public void toastMessage(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
public void toastMessage(int resId) {
Toast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}
}
2、剩下的就是在自定義Application裡建立這個語音合成物件,呼叫它的startSpeak(String content)方法即可,傳入引數就是要播放的語音內容,還可傳入資原始檔對應id;
/*
* 科大訊飛語音宣告
*/
private SpeechUtil_xf mXFSpeech;
private int playType = 1; //用哪種播放,1科大訊飛
private boolean isPlay = true; //是否播放語音
public static SysApplication getInstance() {
return instance;
}
@Override
public void onCreate() {
super.onCreate();
applicationContext = this;
instance = this;
mSpeechUtil = new SpeechUtil(SysApplication.this); //例項化語音合成類
}
3、在哪個地方需要文字轉語音便呼叫Application類的這個方法即可;
public void speak(String content) {
if(isPlay) {
if(playType == 1) {
speaking(content);
}
}
}
public void speak(int resId) {
speak(getString(resId));
}
4、差點忘了,還要申請許可權
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 雲播放需要網路許可權,本地的就不用了 -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
5、大功告成!現在基本的功能已經完成了。