标签:
import java.util.List; import java.util.Locale; import android.app.Activity; import android.os.Bundle; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.EngineInfo; import android.speech.tts.TextToSpeech.OnInitListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; import android.widget.AdapterView.OnItemSelectedListener; public class TTSActivity extends Activity implements OnClickListener { private TextToSpeech mSpeech; private EditText et_tts_resource; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tts); et_tts_resource = (EditText) findViewById(R.id.et_tts_resource); Button btn_tts_start = (Button) findViewById(R.id.btn_tts_start); btn_tts_start.setOnClickListener(this); initLanguageSpinner(); mSpeech = new TextToSpeech(TTSActivity.this, new TTSListener()); } private void initLanguageSpinner() { ArrayAdapter<String> starAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, mLangArray); starAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); Spinner sp = (Spinner) findViewById(R.id.sp_tts_language); sp.setPrompt("请选择语言"); sp.setAdapter(starAdapter); sp.setOnItemSelectedListener(new LanguageSelectedListener()); sp.setSelection(0); } private String[] mEngineArray; private int mEngine; private void initEngineSpinner() { mEngineArray = new String[mEngineList.size()]; for(int i=0; i<mEngineList.size(); i++) { mEngineArray[i] = mEngineList.get(i).label; } ArrayAdapter<String> starAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, mEngineArray); starAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); Spinner sp = (Spinner) findViewById(R.id.sp_tts_engine); sp.setPrompt("请选择引擎"); sp.setAdapter(starAdapter); sp.setOnItemSelectedListener(new EngineSelectedListener()); sp.setSelection(0); } @Override protected void onDestroy() { recycleSpeech(); super.onDestroy(); } private void recycleSpeech() { if (mSpeech != null) { mSpeech.stop(); mSpeech.shutdown(); mSpeech = null; } } private String[] mLangArray = {"英语", "法语", "德语", "意大利语", "汉语普通话" }; private Locale[] mLocaleArray = { Locale.ENGLISH, Locale.FRENCH, Locale.GERMAN, Locale.ITALIAN, Locale.CHINA }; private int mLanguage; private String mTextEN = "hello world. This is a TTS demo."; private String mTextCN = "白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"; private class LanguageSelectedListener implements OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { mLanguage = arg2; if (mLocaleArray[mLanguage]==Locale.SIMPLIFIED_CHINESE || mLocaleArray[mLanguage]==Locale.TRADITIONAL_CHINESE) { et_tts_resource.setText(mTextCN); } else { et_tts_resource.setText(mTextEN); } if (mEngineList != null) { resetLanguage(); } } public void onNothingSelected(AdapterView<?> arg0) { } } private class EngineSelectedListener implements OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { mEngine = arg2; recycleSpeech(); mSpeech = new TextToSpeech(TTSActivity.this, new TTSListener(), mEngineList.get(mEngine).name); } public void onNothingSelected(AdapterView<?> arg0) { } } private void resetLanguage() { int result = mSpeech.setLanguage(mLocaleArray[mLanguage]); //如果打印为-2,说明不支持这种语言;-1说明缺失数据 Toast.makeText(TTSActivity.this, "您选择的是"+mLangArray[mLanguage] +",result="+result, Toast.LENGTH_SHORT).show(); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { } } @Override public void onClick(View v) { if (v.getId() == R.id.btn_tts_start) { String content = et_tts_resource.getText().toString(); int result = mSpeech.speak(content, TextToSpeech.QUEUE_FLUSH, null); Toast.makeText(TTSActivity.this, "speak result="+result, Toast.LENGTH_SHORT).show(); } } private List<EngineInfo> mEngineList; private class TTSListener implements OnInitListener { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { if (mEngineList == null) { mEngineList = mSpeech.getEngines(); initEngineSpinner(); } else { resetLanguage(); } } } } }
SpeechUtility.createUtility(MainApplication.this, "appid=5763c4cf");4、在AndroidManifest.xml中加入必要的权限,以及自定义的Application类;
import java.util.HashMap; import java.util.LinkedHashMap; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Toast; import com.example.exmvoice.R; import com.example.exmvoice.SettingsActivity; import com.example.exmvoice.xunfei.util.FucUtil; import com.example.exmvoice.xunfei.util.JsonParser; import com.iflytek.cloud.ErrorCode; import com.iflytek.cloud.InitListener; import com.iflytek.cloud.RecognizerListener; import com.iflytek.cloud.RecognizerResult; import com.iflytek.cloud.SpeechConstant; import com.iflytek.cloud.SpeechError; import com.iflytek.cloud.SpeechRecognizer; import com.iflytek.cloud.ui.RecognizerDialog; import com.iflytek.cloud.ui.RecognizerDialogListener; public class XFRecognizeActivity extends Activity implements OnClickListener { private final static String TAG = XFRecognizeActivity.class.getSimpleName(); // 语音听写对象 private SpeechRecognizer mRecognize; // 语音听写UI private RecognizerDialog mRecognizeDialog; // 用HashMap存储听写结果 private HashMap<String, String> mRecognizeResults = new LinkedHashMap<String, String>(); private EditText mResultText; private SharedPreferences mSharedPreferences; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_xunfei_recognize); mResultText = ((EditText) findViewById(R.id.xf_recognize_text)); findViewById(R.id.xf_recognize_start).setOnClickListener(this); findViewById(R.id.xf_recognize_stop).setOnClickListener(this); findViewById(R.id.xf_recognize_cancel).setOnClickListener(this); findViewById(R.id.xf_recognize_stream).setOnClickListener(this); findViewById(R.id.xf_recognize_setting).setOnClickListener(this); mSharedPreferences = getSharedPreferences(SettingsActivity.PREFER_NAME, Activity.MODE_PRIVATE); // 初始化识别无UI识别对象,使用SpeechRecognizer对象,可根据回调消息自定义界面; mRecognize = SpeechRecognizer.createRecognizer(this, mInitListener); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer // 使用UI听写功能,请将assets下文件拷贝到项目中 mRecognizeDialog = new RecognizerDialog(this, mInitListener); } @Override protected void onDestroy() { super.onDestroy(); // 退出时释放连接 mRecognize.cancel(); mRecognize.destroy(); } @Override public void onClick(View v) { int ret = 0; // 函数调用返回值 int resid = v.getId(); if (resid == R.id.xf_recognize_setting) { // 进入参数设置页面 Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra("type", SettingsActivity.XF_RECOGNIZE); startActivity(intent); } else if (resid == R.id.xf_recognize_start) { // 开始听写。如何判断一次听写结束:OnResult isLast=true 或者 onError mResultText.setText(null);// 清空显示内容 mRecognizeResults.clear(); // 设置参数 resetParam(); boolean isShowDialog = mSharedPreferences.getBoolean("show_dialog", true); if (isShowDialog) { // 显示听写对话框 mRecognizeDialog.setListener(mRecognizeDialogListener); mRecognizeDialog.show(); showTip("请开始说话………"); } else { // 不显示听写对话框 ret = mRecognize.startListening(mRecognizeListener); if (ret != ErrorCode.SUCCESS) { showTip("听写失败,错误码:" + ret); } else { showTip("请开始说话…"); } } } else if (resid == R.id.xf_recognize_stop) { // 停止听写 mRecognize.stopListening(); showTip("停止听写"); } else if (resid == R.id.xf_recognize_cancel) { // 取消听写 mRecognize.cancel(); showTip("取消听写"); } else if (resid == R.id.xf_recognize_stream) { // 音频流识别 mResultText.setText(null);// 清空显示内容 mRecognizeResults.clear(); // 设置参数 resetParam(); // 设置音频来源为外部文件 mRecognize.setParameter(SpeechConstant.AUDIO_SOURCE, "-1"); // 也可以像以下这样直接设置音频文件路径识别(要求设置文件在sdcard上的全路径): // mRecognize.setParameter(SpeechConstant.AUDIO_SOURCE, "-2"); // mRecognize.setParameter(SpeechConstant.ASR_SOURCE_PATH, "sdcard/XXX/XXX.pcm"); ret = mRecognize.startListening(mRecognizeListener); if (ret != ErrorCode.SUCCESS) { showTip("识别失败,错误码:" + ret); } else { byte[] audioData = FucUtil.readAudioFile(this, "retcognize_est.wav"); if (null != audioData) { showTip("开始音频流识别"); // 一次(也可以分多次)写入音频文件数据,数据格式必须是采样率为8KHz或16KHz(本地识别只支持16K采样率,云端都支持),位长16bit,单声道的wav或者pcm // 写入8KHz采样的音频时,必须先调用setParameter(SpeechConstant.SAMPLE_RATE, "8000")设置正确的采样率 // 注:当音频过长,静音部分时长超过VAD_EOS将导致静音后面部分不能识别 mRecognize.writeAudio(audioData, 0, audioData.length); mRecognize.stopListening(); } else { mRecognize.cancel(); showTip("读取音频流失败"); } } } } //初始化监听器 private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d(TAG, "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { showTip("初始化失败,错误码:" + code); } } }; //听写监听器 private RecognizerListener mRecognizeListener = new RecognizerListener() { @Override public void onBeginOfSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 showTip("开始说话"); } @Override public void onError(SpeechError error) { // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。 // 如果使用本地功能(语记)需要提示用户开启语记的录音权限。 showTip(error.getPlainDescription(true)); } @Override public void onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 showTip("结束说话"); } @Override public void onResult(RecognizerResult results, boolean isLast) { Log.d(TAG, results.getResultString()); printResult(results); if (isLast) { // TODO 最后的结果 } } @Override public void onVolumeChanged(int volume, byte[] data) { showTip("当前正在说话,音量大小:" + volume); Log.d(TAG, "返回音频数据:"+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); // Log.d(TAG, "session id =" + sid); // } } }; private void printResult(RecognizerResult results) { String text = JsonParser.parseIatResult(results.getResultString()); String sn = null; try { JSONObject resultJson = new JSONObject(results.getResultString()); sn = resultJson.optString("sn"); } catch (JSONException e) { e.printStackTrace(); return; } mRecognizeResults.put(sn, text); StringBuffer resultBuffer = new StringBuffer(); for (String key : mRecognizeResults.keySet()) { resultBuffer.append(mRecognizeResults.get(key)); } mResultText.setText(resultBuffer.toString()); mResultText.setSelection(mResultText.length()); } //听写UI监听器 private RecognizerDialogListener mRecognizeDialogListener = new RecognizerDialogListener() { public void onResult(RecognizerResult results, boolean isLast) { printResult(results); } //识别回调错误 public void onError(SpeechError error) { showTip(error.getPlainDescription(true)); } }; private void showTip(final String str) { Toast.makeText(this, str, Toast.LENGTH_LONG).show(); } //参数设置 public void resetParam() { // 清空参数 mRecognize.setParameter(SpeechConstant.PARAMS, null); // 设置听写引擎。TYPE_LOCAL表示本地,TYPE_CLOUD表示云端,TYPE_MIX 表示混合 mRecognize.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); // 设置返回结果格式 mRecognize.setParameter(SpeechConstant.RESULT_TYPE, "json"); String lag = mSharedPreferences.getString("recognize_language_preference", "mandarin"); if (lag.equals("en_us")) { // 设置语言 mRecognize.setParameter(SpeechConstant.LANGUAGE, "en_us"); } else { mRecognize.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); // 设置语言区域 mRecognize.setParameter(SpeechConstant.ACCENT, lag); } // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 mRecognize.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("recognize_vadbos_preference", "4000")); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 mRecognize.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("recognize_vadeos_preference", "1000")); // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 mRecognize.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("recognize_punc_preference", "1")); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 // 注:AUDIO_FORMAT参数语记需要更新版本才能生效 mRecognize.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); mRecognize.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/recognize.wav"); } }
import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Toast; import com.example.exmvoice.R; import com.example.exmvoice.SettingsActivity; 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.SynthesizerListener; public class XFComposeActivity extends Activity implements OnClickListener { private static String TAG = XFComposeActivity.class.getSimpleName(); // 语音合成对象 private SpeechSynthesizer mCompose; // 默认发音人 private String voicer = "xiaoyan"; private String[] mCloudVoicersEntries; private String[] mCloudVoicersValue ; // 缓冲进度 private int mPercentForBuffering = 0; // 播放进度 private int mPercentForPlaying = 0; private EditText mResourceText; private SharedPreferences mSharedPreferences; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_xunfei_compose); mResourceText = ((EditText) findViewById(R.id.xf_compose_text)); findViewById(R.id.xf_compose_play).setOnClickListener(this); findViewById(R.id.xf_compose_cancel).setOnClickListener(this); findViewById(R.id.xf_compose_pause).setOnClickListener(this); findViewById(R.id.xf_compose_resume).setOnClickListener(this); findViewById(R.id.xf_compose_setting).setOnClickListener(this); findViewById(R.id.xf_compose_person).setOnClickListener(this); mSharedPreferences = getSharedPreferences(SettingsActivity.PREFER_NAME, MODE_PRIVATE); // 初始化合成对象 mCompose = SpeechSynthesizer.createSynthesizer(this, mComposeInitListener); // 云端发音人名称列表 mCloudVoicersEntries = getResources().getStringArray(R.array.voicer_cloud_entries); mCloudVoicersValue = getResources().getStringArray(R.array.voicer_cloud_values); } @Override protected void onDestroy() { super.onDestroy(); // 退出时释放连接 mCompose.stopSpeaking(); mCompose.destroy(); } @Override public void onClick(View v) { int resid = v.getId(); if (resid == R.id.xf_compose_setting) { Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra("type", SettingsActivity.XF_COMPOSE); startActivity(intent); } else if (resid == R.id.xf_compose_play) { // 开始合成 //收到onCompleted 回调时,合成结束、生成合成音频。合成的音频格式:只支持pcm格式 String text = mResourceText.getText().toString(); // 设置参数 setParam(); int code = mCompose.startSpeaking(text, mComposeListener); if (code != ErrorCode.SUCCESS) { showTip("语音合成失败,错误码: " + code); } // //只保存音频不进行播放接口,调用此接口请注释startSpeaking接口 // //text:要合成的文本,uri:需要保存的音频全路径,listener:回调接口 // String path = Environment.getExternalStorageDirectory()+"/compose.pcm"; // int code = mCompose.synthesizeToUri(text, path, mComposeListener); } else if (resid == R.id.xf_compose_cancel) { // 取消合成 mCompose.stopSpeaking(); } else if (resid == R.id.xf_compose_pause) { // 暂停播放 mCompose.pauseSpeaking(); } else if (resid == R.id.xf_compose_resume) { // 继续播放 mCompose.resumeSpeaking(); } else if (resid == R.id.xf_compose_person) { // 选择发音人 showPresonSelectDialog(); } } private int selectedNum = 0; //发音人选择 private void showPresonSelectDialog() { new AlertDialog.Builder(this).setTitle("在线合成发音人选项") .setSingleChoiceItems(mCloudVoicersEntries, // 单选框有几项,各是什么名字 selectedNum, // 默认的选项 new DialogInterface.OnClickListener() { // 点击单选框后的处理 public void onClick(DialogInterface dialog, int which) { // 点击了哪一项 voicer = mCloudVoicersValue[which]; if ("catherine".equals(voicer) || "henry".equals(voicer) || "vimary".equals(voicer) || "Mariane".equals(voicer) || "Allabent".equals(voicer) || "Gabriela".equals(voicer) || "Abha".equals(voicer) || "XiaoYun".equals(voicer)) { mResourceText.setText(R.string.compose_source_en); } else { mResourceText.setText(R.string.compose_source); } selectedNum = which; dialog.dismiss(); } }).show(); } //初始化监听 private InitListener mComposeInitListener = new InitListener() { @Override public void onInit(int code) { Log.d(TAG, "InitListener init() code = " + code); if (code != ErrorCode.SUCCESS) { showTip("初始化失败,错误码:"+code); } else { // 初始化成功,之后可以调用startSpeaking方法 // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成, // 正确的做法是将onCreate中的startSpeaking调用移至这里 } } }; //合成回调监听 private SynthesizerListener mComposeListener = 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.xf_compose_toast_format), mPercentForBuffering, mPercentForPlaying)); } @Override public void onSpeakProgress(int percent, int beginPos, int endPos) { // 播放进度 mPercentForPlaying = percent; showTip(String.format(getString(R.string.xf_compose_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); // } } }; private void showTip(final String str) { Toast.makeText(this, str, Toast.LENGTH_LONG).show(); } //参数设置 private void setParam(){ // 清空参数 mCompose.setParameter(SpeechConstant.PARAMS, null); // 根据合成引擎设置相应参数 mCompose.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); // 设置在线合成发音人 mCompose.setParameter(SpeechConstant.VOICE_NAME, voicer); //设置合成语速 mCompose.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50")); //设置合成音调 mCompose.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50")); //设置合成音量 mCompose.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50")); //设置播放器音频流类型 mCompose.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3")); // 设置播放合成音频打断音乐播放,默认为true mCompose.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true"); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 // 注:AUDIO_FORMAT参数语记需要更新版本才能生效 mCompose.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); mCompose.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/compose.wav"); } }
import com.example.exmvoice.R; import com.example.exmvoice.SettingsActivity; import com.example.exmvoice.xunfei.util.SettingTextWatcher; import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceFragment; //语音识别设置界面 public class XFRecognizeSettingsFragment extends PreferenceFragment implements OnPreferenceChangeListener { private EditTextPreference mVadbosPreference; private EditTextPreference mVadeosPreference; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getPreferenceManager().setSharedPreferencesName(SettingsActivity.PREFER_NAME); addPreferencesFromResource(R.xml.xf_recognize_setting); mVadbosPreference = (EditTextPreference) findPreference("recognize_vadbos_preference"); mVadbosPreference.getEditText().addTextChangedListener( new SettingTextWatcher(getActivity(),mVadbosPreference,0,10000)); mVadeosPreference = (EditTextPreference) findPreference("recognize_vadeos_preference"); mVadeosPreference.getEditText().addTextChangedListener( new SettingTextWatcher(getActivity(),mVadeosPreference,0,10000)); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { return true; } }
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <ListPreference android:key="recognize_language_preference" android:title="语言设置" android:entries="@array/language_entries" android:entryValues="@array/language_values" android:summary="支持:普通话,粤语,河南话,英语 " android:defaultValue="mandarin" /> <EditTextPreference android:key="recognize_vadbos_preference" android:title="前端点超时" android:dialogTitle="请输入时间(0-10000)ms" android:summary="默认值:短信转写5000,其他4000" android:defaultValue="5000" /> <EditTextPreference android:key="recognize_vadeos_preference" android:title="后端点超时" android:dialogTitle="请输入时间(0-10000)ms" android:summary="默认值:短信转写1800,其他700 " android:defaultValue="1800" /> <ListPreference android:key="recognize_punc_preference" android:title="标点符号" android:entries="@array/punc_entries" android:entryValues="@array/punc_values" android:summary="默认值:有标点 " android:defaultValue="1" /> <CheckBoxPreference android:key="show_dialog" android:title="显示听写界面" android:defaultValue="true" /> </PreferenceScreen>
<meta-data android:name="com.baidu.speech.APP_ID" android:value="8282403"/> <meta-data android:name="com.baidu.speech.API_KEY" android:value="M2OT6nhn1beu4IxI5GqQk4ev"/> <meta-data android:name="com.baidu.speech.SECRET_KEY" android:value="6e448840e00a12881c6d63346771caa5"/> <service android:name="com.baidu.speech.VoiceRecognitionService" android:exported="false" /> <activity android:name="com.baidu.voicerecognition.android.ui.BaiduASRDigitalDialog" android:configChanges="orientation|keyboardHidden|screenLayout" android:theme="@android:style/Theme.Dialog" android:exported="false" android:screenOrientation="portrait"> <intent-filter> <action android:name="com.baidu.action.RECOGNIZE_SPEECH" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>4、demo工程中assets目录下的文件原样拷过来;
import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.speech.RecognitionListener; import android.speech.SpeechRecognizer; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.*; import com.baidu.speech.VoiceRecognitionService; import com.example.exmvoice.R; import com.example.exmvoice.SettingsActivity; import com.example.exmvoice.baidu.setting.Constant; import org.json.JSONObject; import java.util.*; public class BDRecognizeActivity extends Activity implements OnClickListener { private static final String TAG = BDRecognizeActivity.class.getSimpleName(); private static final int REQUEST_UI = 1; private TextView txtResult; private TextView txtLog; private Button btnStart; public static final int STATUS_None = 0; public static final int STATUS_WaitingReady = 2; public static final int STATUS_Ready = 3; public static final int STATUS_Speaking = 4; public static final int STATUS_Recognition = 5; private SpeechRecognizer speechRecognizer; private int status = STATUS_None; private long speechEndTime = -1; private static final int EVENT_ERROR = 11; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_baidu_recognize); txtResult = (TextView) findViewById(R.id.bd_recognize_text); txtLog = (TextView) findViewById(R.id.bd_recognize_log); btnStart = (Button) findViewById(R.id.bd_recognize_start); btnStart.setOnClickListener(this); findViewById(R.id.bd_recognize_setting).setOnClickListener(this); speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this, new ComponentName(this, VoiceRecognitionService.class)); speechRecognizer.setRecognitionListener(mRecognitionListener); } @Override protected void onDestroy() { speechRecognizer.destroy(); super.onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { mRecognitionListener.onResults(data.getExtras()); } else { status = STATUS_None; btnStart.setText("开始"); } } public void bindParams(Intent intent) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); if (sp.getBoolean("tips_sound", true)) { intent.putExtra(Constant.EXTRA_SOUND_START, R.raw.bdspeech_recognition_start); intent.putExtra(Constant.EXTRA_SOUND_END, R.raw.bdspeech_speech_end); intent.putExtra(Constant.EXTRA_SOUND_SUCCESS, R.raw.bdspeech_recognition_success); intent.putExtra(Constant.EXTRA_SOUND_ERROR, R.raw.bdspeech_recognition_error); intent.putExtra(Constant.EXTRA_SOUND_CANCEL, R.raw.bdspeech_recognition_cancel); } if (sp.contains(Constant.EXTRA_INFILE)) { String tmp = sp.getString(Constant.EXTRA_INFILE, "").replaceAll(",.*", "").trim(); intent.putExtra(Constant.EXTRA_INFILE, tmp); } if (sp.getBoolean(Constant.EXTRA_OUTFILE, false)) { intent.putExtra(Constant.EXTRA_OUTFILE, "sdcard/outfile.pcm"); } if (sp.contains(Constant.EXTRA_SAMPLE)) { String tmp = sp.getString(Constant.EXTRA_SAMPLE, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_SAMPLE, Integer.parseInt(tmp)); } } if (sp.contains(Constant.EXTRA_LANGUAGE)) { String tmp = sp.getString(Constant.EXTRA_LANGUAGE, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_LANGUAGE, tmp); } } if (sp.contains(Constant.EXTRA_NLU)) { String tmp = sp.getString(Constant.EXTRA_NLU, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_NLU, tmp); } } if (sp.contains(Constant.EXTRA_VAD)) { String tmp = sp.getString(Constant.EXTRA_VAD, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_VAD, tmp); } } if (sp.contains(Constant.EXTRA_PROP)) { String tmp = sp.getString(Constant.EXTRA_PROP, "").replaceAll(",.*", "").trim(); if (null != tmp && !"".equals(tmp)) { intent.putExtra(Constant.EXTRA_PROP, Integer.parseInt(tmp)); } } } private void start() { btnStart.setText("取消"); txtLog.setText(""); status = STATUS_WaitingReady; print("点击了“开始”"); Intent intent = new Intent(); bindParams(intent); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); { String args = sp.getString("args", ""); if (null != args) { print("参数集:" + args); intent.putExtra("args", args); } } boolean api = sp.getBoolean("api", false); if (api) { speechEndTime = -1; speechRecognizer.startListening(intent); } else { intent.setAction("com.baidu.action.RECOGNIZE_SPEECH"); startActivityForResult(intent, REQUEST_UI); } txtResult.setText(""); } private void stop() { speechRecognizer.stopListening(); status = STATUS_Recognition; btnStart.setText("识别中"); print("点击了“说完了”"); } private void cancel() { speechRecognizer.cancel(); btnStart.setText("开始"); status = STATUS_None; print("点击了“取消”"); } private RecognitionListener mRecognitionListener = new RecognitionListener() { @Override public void onReadyForSpeech(Bundle params) { status = STATUS_Ready; print("准备就绪,可以开始说话"); } @Override public void onBeginningOfSpeech() { status = STATUS_Speaking; btnStart.setText("说完了"); print("检测到用户已经开始说话"); } @Override public void onRmsChanged(float rmsdB) { } @Override public void onBufferReceived(byte[] buffer) { } @Override public void onEndOfSpeech() { speechEndTime = System.currentTimeMillis(); status = STATUS_Recognition; print("检测到用户已经停止说话"); btnStart.setText("识别中"); } @Override public void onError(int error) { status = STATUS_None; StringBuilder sb = new StringBuilder(); switch (error) { case SpeechRecognizer.ERROR_AUDIO: sb.append("音频问题"); break; case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: sb.append("没有语音输入"); break; case SpeechRecognizer.ERROR_CLIENT: sb.append("其它客户端错误"); break; case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: sb.append("权限不足"); break; case SpeechRecognizer.ERROR_NETWORK: sb.append("网络问题"); break; case SpeechRecognizer.ERROR_NO_MATCH: sb.append("没有匹配的识别结果"); break; case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: sb.append("引擎忙"); break; case SpeechRecognizer.ERROR_SERVER: sb.append("服务端错误"); break; case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: sb.append("连接超时"); break; } sb.append(":" + error); print("识别失败:" + sb.toString()); btnStart.setText("开始"); } @Override public void onResults(Bundle results) { long end2finish = System.currentTimeMillis() - speechEndTime; ArrayList<String> nbest = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); print("识别成功:" + Arrays.toString(nbest.toArray(new String[nbest.size()]))); String json_res = results.getString("origin_result"); try { print("origin_result=\n" + new JSONObject(json_res).toString(4)); } catch (Exception e) { print("origin_result=[warning: bad json]\n" + json_res); } String strEnd2Finish = ""; if (end2finish < 60 * 1000) { strEnd2Finish = "(waited " + end2finish + "ms)"; } txtResult.setText(nbest.get(0) + strEnd2Finish); status = STATUS_None; btnStart.setText("开始"); } @Override public void onPartialResults(Bundle partialResults) { ArrayList<String> nbest = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if (nbest.size() > 0) { print("~临时识别结果:" + Arrays.toString(nbest.toArray(new String[0]))); txtResult.setText(nbest.get(0)); } } @Override public void onEvent(int eventType, Bundle params) { switch (eventType) { case EVENT_ERROR: String reason = params.get("reason") + ""; print("EVENT_ERROR, " + reason); status = STATUS_None; btnStart.setText("开始"); break; case VoiceRecognitionService.EVENT_ENGINE_SWITCH: int type = params.getInt("engine_type"); print("*引擎切换至" + (type == 0 ? "在线" : "离线")); break; } } }; private void print(String msg) { txtLog.append(msg + "\n"); ScrollView sv = (ScrollView) txtLog.getParent(); sv.smoothScrollTo(0, 1000000); Log.d(TAG, "----" + msg); } @Override public void onClick(View v) { int resid = v.getId(); if (resid == R.id.bd_recognize_setting) { Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra("type", SettingsActivity.BD_RECOGNIZE); startActivity(intent); } else if (resid == R.id.bd_recognize_start) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); boolean api = sp.getBoolean("api", false); if (api) { if (status == STATUS_None) { start(); } else if (status == STATUS_WaitingReady || status == STATUS_Ready || status == STATUS_Recognition) { cancel(); } else if (status == STATUS_Speaking) { stop(); } } else { start(); } } } }
import java.io.File; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.media.AudioManager; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.Toast; import com.baidu.tts.auth.AuthInfo; import com.baidu.tts.client.SpeechError; import com.baidu.tts.client.SpeechSynthesizer; import com.baidu.tts.client.SpeechSynthesizerListener; import com.baidu.tts.client.TtsMode; import com.example.exmvoice.R; import com.example.exmvoice.SettingsActivity; import com.example.exmvoice.baidu.util.AssetsUtil; public class BDComposeActivity extends Activity implements OnClickListener,OnCheckedChangeListener { private static String TAG = BDComposeActivity.class.getSimpleName(); private SpeechSynthesizer mSpeechSynthesizer; private String mSampleDirPath; private static final String SAMPLE_DIR_NAME = "baiduTTS"; 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 LICENSE_FILE_NAME = "bd_temp_license"; 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"; private boolean bOnline = true; private EditText mResourceText; private SharedPreferences mSharedPreferences; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_baidu_compose); mResourceText = ((EditText) findViewById(R.id.bd_compose_text)); ((RadioGroup)findViewById(R.id.bd_compose_mode)).setOnCheckedChangeListener(this); findViewById(R.id.bd_compose_play).setOnClickListener(this); findViewById(R.id.bd_compose_cancel).setOnClickListener(this); findViewById(R.id.bd_compose_pause).setOnClickListener(this); findViewById(R.id.bd_compose_resume).setOnClickListener(this); findViewById(R.id.bd_compose_setting).setOnClickListener(this); mSharedPreferences = getSharedPreferences(SettingsActivity.PREFER_NAME, MODE_PRIVATE); initialEnv(); initialEngine(); } private void initialEnv() { if (mSampleDirPath == null) { String sdcardPath = Environment.getExternalStorageDirectory().toString(); mSampleDirPath = sdcardPath + "/" + SAMPLE_DIR_NAME; } File file = new File(mSampleDirPath); if (!file.exists()) { file.mkdirs(); } AssetsUtil.copyFromAssetsToSdcard(this, false, SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_FEMALE_MODEL_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_MALE_MODEL_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, TEXT_MODEL_NAME, mSampleDirPath + "/" + TEXT_MODEL_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, LICENSE_FILE_NAME, mSampleDirPath + "/" + LICENSE_FILE_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, "english/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, "english/" + ENGLISH_SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_SPEECH_MALE_MODEL_NAME); AssetsUtil.copyFromAssetsToSdcard(this, false, "english/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME); } private void initialEngine() { mSpeechSynthesizer = SpeechSynthesizer.getInstance(); mSpeechSynthesizer.setContext(this); mSpeechSynthesizer.setSpeechSynthesizerListener(mSpeechListener); ApplicationInfo appInfo = null; try { appInfo = this.getPackageManager().getApplicationInfo( getPackageName(), PackageManager.GET_META_DATA); String app_id = appInfo.metaData.getString("com.baidu.speech.APP_ID"); String api_key = appInfo.metaData.getString("com.baidu.speech.API_KEY"); String secret_key = appInfo.metaData.getString("com.baidu.speech.SECRET_KEY"); mSpeechSynthesizer.setAppId(app_id); mSpeechSynthesizer.setApiKey(api_key, secret_key); } catch (NameNotFoundException e) { e.printStackTrace(); showTip("获取appid失败"); } AuthInfo authInfo = mSpeechSynthesizer.auth(TtsMode.ONLINE); if (authInfo.isSuccess()) { showTip("auth success"); } else { String errorMsg = authInfo.getTtsError().getDetailMessage(); showTip("auth failed errorMsg=" + errorMsg); } mSpeechSynthesizer.initTts(TtsMode.MIX); bOnline = ((RadioButton) findViewById(R.id.bd_compose_online)).isChecked(); setParams(bOnline); } @Override protected void onDestroy() { // 退出时释放连接 mSpeechSynthesizer.release(); super.onDestroy(); } @Override public void onClick(View v) { int resid = v.getId(); if (resid == R.id.bd_compose_setting) { Intent intent = new Intent(this, SettingsActivity.class); intent.putExtra("type", SettingsActivity.BD_COMPOSE); startActivity(intent); } else if (resid == R.id.bd_compose_play) { // 开始合成 speak(); } else if (resid == R.id.bd_compose_cancel) { // 取消合成 mSpeechSynthesizer.stop(); } else if (resid == R.id.bd_compose_pause) { // 暂停播放 mSpeechSynthesizer.pause(); } else if (resid == R.id.bd_compose_resume) { // 继续播放 mSpeechSynthesizer.resume(); } } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if (checkedId == R.id.bd_compose_online) { bOnline = true; } else if (checkedId == R.id.bd_compose_offline) { bOnline = false; } Log.d(TAG, "bOnline="+bOnline); setParams(bOnline); } private void setParams(boolean online) { mSpeechSynthesizer.setAudioStreamType(AudioManager.STREAM_MUSIC); //setVolumeControlStream(AudioManager.STREAM_MUSIC); mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, mSharedPreferences.getString("bd_person_preference", "0")); //0--普通女声,1--普通男声,2--特别男声,3--情感男声 mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, mSharedPreferences.getString("bd_volume_preference", "5")); //音量,取值0-9,默认为5中音量 mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, mSharedPreferences.getString("bd_speed_preference", "5")); //语速,取值0-9,默认为5中语速 mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, mSharedPreferences.getString("bd_pitch_preference", "5")); //音调,取值0-9,默认为5中语调 mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_ENCODE, SpeechSynthesizer.AUDIO_ENCODE_AMR); mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_RATE, SpeechSynthesizer.AUDIO_BITRATE_AMR_15K85); if (online == true) { } else { // 文本模型文件路径 (离线引擎使用) 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文件时需要进行设置,如果在[应用管理]中开通了离线授权,不需要设置该参数,建议将该行代码删除(离线引擎) mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_LICENCE_FILE, mSampleDirPath + "/" + LICENSE_FILE_NAME); // 设置Mix模式的合成策略 mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT); // 加载离线英文资源(提供离线英文合成功能) String englishTextPath = mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME; String englishSpeechPath = mSampleDirPath + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME; Log.d(TAG, "englishTextPath="+englishTextPath+", englishSpeechPath="+englishSpeechPath); int result = mSpeechSynthesizer.loadEnglishModel(englishTextPath, englishSpeechPath); showTip("loadEnglishModel result=" + result); //如果initTts使用的是在线模式TtsMode.ONLINE,则loadEnglishModel会失败返回-11 } } private void speak() { final String text = mResourceText.getText().toString(); if (text==null || text.length()<=0) { showTip("请输入要合成语音的文字"); } else { int result = mSpeechSynthesizer.speak(text); if (result < 0) { showTip("result="+result+". error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 "); } else { showTip("合成结果="+result); } } } private SpeechSynthesizerListener mSpeechListener = new SpeechSynthesizerListener() { @Override public void onSynthesizeStart(String utteranceId) { toPrint("onSynthesizeStart utteranceId=" + utteranceId); } @Override public void onSynthesizeDataArrived(String utteranceId, byte[] data, int progress) { // toPrint("onSynthesizeDataArrived"); } @Override public void onSynthesizeFinish(String utteranceId) { toPrint("onSynthesizeFinish utteranceId=" + utteranceId); } @Override public void onSpeechStart(String utteranceId) { toPrint("onSpeechStart utteranceId=" + utteranceId); } @Override public void onSpeechProgressChanged(String utteranceId, int progress) { // toPrint("onSpeechProgressChanged"); } @Override public void onSpeechFinish(String utteranceId) { toPrint("onSpeechFinish utteranceId=" + utteranceId); } @Override public void onError(String utteranceId, SpeechError error) { toPrint("onError error=" + "(" + error.code + ")" + error.description + "--utteranceId=" + utteranceId); } }; private void showTip(final String str) { Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); String message = (String) msg.obj; if (message != null) { Log.d(TAG, message); showTip(message); } } }; private void toPrint(String str) { Message msg = Message.obtain(); msg.obj = str; this.mHandler.sendMessage(msg); } }
标签:
原文地址:http://blog.csdn.net/aqi00/article/details/51766208