TextToSpeech,简称 TTS,是Android 1.6版本中比较重要的新功能。将所指定的文本转成不同语言音频输出。它可以方便的嵌入到游戏或者应用程序中,增强用户体验。
TTS Engine,依托于当前Android Platform所支持的几种主要语言:English、French、German、Italian及Spanish五大语言(暂时没有直接中文)。TTS可以将文本随意的转换成以上任意五种语言的语音输出。
界面中组件的设计很简单,分为四个部分:
1、内容编辑框,供用户输入需要转换成语音的文本;
2、音频播放按钮,点击后播放文本对应的音频;
3、语调编辑框,供用户调节朗读的语调,支持浮点型数据,默认值为1.0;
4、语速编辑框,供用户调节语速的语速,只能为整型数据,默认值为1;
代码如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 android:gravity="center_vertical" 7 tools:context="com.texttospeechtest.MainActivity" > 8 9 <LinearLayout 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:orientation="horizontal" 13 android:layout_gravity="center_horizontal" 14 android:gravity="center_horizontal" > 15 16 <TextView 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:text="@string/speak_content" 20 android:textColor="#f00" /> 21 22 <EditText android:id="@+id/input_something" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:hint="@string/input_something" /> 26 27 </LinearLayout> 28 29 <Button android:id="@+id/to_speak" 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" 32 android:layout_gravity="center_horizontal" 33 android:layout_marginTop="40dp" 34 android:text="@string/to_speak" /> 35 36 <Button android:id="@+id/save_wav" 37 android:layout_width="wrap_content" 38 android:layout_height="wrap_content" 39 android:layout_gravity="center_horizontal" 40 android:layout_marginTop="40dp" 41 android:text="@string/save_wav" /> 42 43 <LinearLayout 44 android:layout_width="wrap_content" 45 android:layout_height="wrap_content" 46 android:orientation="horizontal" 47 android:layout_gravity="center_horizontal" 48 android:gravity="center_horizontal" 49 android:layout_marginTop="40dp" > 50 51 <TextView 52 android:layout_width="wrap_content" 53 android:layout_height="wrap_content" 54 android:text="@string/pitch_level_name" 55 android:textColor="#f00" /> 56 57 <EditText android:id="@+id/pitch_level" 58 android:layout_width="wrap_content" 59 android:layout_height="wrap_content" 60 android:hint="@string/pitch_level" 61 android:text="@string/pitch_level" /> 62 63 </LinearLayout> 64 65 <LinearLayout 66 android:layout_width="wrap_content" 67 android:layout_height="wrap_content" 68 android:orientation="horizontal" 69 android:layout_gravity="center_horizontal" 70 android:gravity="center_horizontal" 71 android:layout_marginTop="40dp" > 72 73 <TextView 74 android:layout_width="wrap_content" 75 android:layout_height="wrap_content" 76 android:text="@string/speak_rate_name" 77 android:textColor="#f00" /> 78 79 <EditText android:id="@+id/speak_rate" 80 android:layout_width="wrap_content" 81 android:layout_height="wrap_content" 82 android:hint="@string/speak_rate" 83 android:text="@string/speak_rate" /> 84 85 </LinearLayout> 86 87 </LinearLayout>
其中用到的字符串定义在values/strings.xml文件中:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <string name="app_name">TextToSpeechTest</string> 5 <string name="hello_world">Hello world!</string> 6 <string name="action_settings">Settings</string> 7 <string name="speak_content">Speak Content: </string> 8 <string name="input_something">Input Something</string> 9 <string name="to_speak">To Speak</string> 10 <string name="pitch_level_name">Pitch Level(float): </string> 11 <string name="pitch_level">1.0</string> 12 <string name="speak_rate_name">Speak Rate(int): </string> 13 <string name="speak_rate">1</string> 14 15 </resources>
TTS应用
1、在应用程序中实现TTS的TextToSpeech.OnInitListener监听器,测试案例针对onInit(int status)和onDestroy()两个方法进行了重载。代码如下:
1 @Override 2 public void onInit(int status) { 3 // TODO Auto-generated method stub 4 if (status == TextToSpeech.SUCCESS) { 5 int result = tts.setLanguage(Locale.US); 6 7 if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { 8 Log.e("TTS", "This Language is not supported"); 9 speak.setEnabled(false); 10 } else { 11 speak.setEnabled(true); 12 } 13 } else { 14 Log.e("TTS", "Initilization Failed!"); 15 } 16 }
1 @Override 2 public void onDestroy() { 3 // Don't forget to shutdown tts! 4 if (tts != null) { 5 tts.stop(); 6 tts.shutdown(); 7 } 8 super.onDestroy(); 9 }
2、对TTS、Button及EditText组件的对象进行初始化,是在主类MainActivity的重载方法onCreate(Bundle savedInstanceState) 中实现,代码如下:
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 setContentView(R.layout.activity_main); 5 6 tts = new TextToSpeech(this, this); 7 content = (EditText)findViewById(R.id.input_something); 8 speak = (Button)findViewById(R.id.to_speak); 9 10 pitch = (EditText)findViewById(R.id.pitch_level); 11 rate = (EditText)findViewById(R.id.speak_rate); 12 13 speak.setOnClickListener(new OnClickListener(){ 14 @Override 15 public void onClick(View v) { 16 // TODO Auto-generated method stub 17 ToSpeak(); 18 } 19 20 });21 }
注意,在定义TTS对象tts时会对上面定义的onInit(int status)方法进行调用,这个过程非常关键。本案例中让其完成的事情包括:
A、判断初始化状态;
B、若成功,设置文本转换语言环境;
C、若语言环境存在并支持,则继续.....
3、点击音频播放按钮后,响应方法为ToSpeak(),其实现如下:
1 public void ToSpeak(){ 2 //to speak input content 3 String c = content.getText().toString(); 4 if(c.equals("")){ 5 Toast.makeText(this, "Please input something first.", Toast.LENGTH_SHORT).show(); 6 } 7 else{ 8 //set speak pitch 9 Float p = Float.valueOf(pitch.getText().toString()); 10 tts.setPitch(p); 11 12 //set speak rate 13 int r = Integer.valueOf(rate.getText().toString()); 14 tts.setSpeechRate(r); 15 16 tts.speak(c, TextToSpeech.QUEUE_FLUSH, null); 17 } 18 }
这里的代码就好理解了,主要是在获取用户输入的文本、语调及语速之后,进行音频的播放。注意:方法开头对文本编辑框中的内容进行了空字串(“” )判断,若为空则没有播放的必要。
虽然界面很简陋,还是附上几张图片把,毕竟是学习的成果。
输入不能为空的提示界面:
在US语言环境下,英文与中文输入(但只有英文能正常朗读):
按照上述流程,英语(US)语言环境可以正常,其他四国语言未测试(按Google说明应该不成问题)。
资料显示TTS暂时不支持中文,但是在设置语言环境时,写入如下代码:
1 int result = tts.setLanguage(Locale.CHINA);
或:
1 int result = tts.setLanguage(Locale.CHINESE);
奇怪的是工程并没有报错,而且运行后按钮是使能状态,说明通过了语言存在与支持的判断环节。不过输入中文,点击之后是没有任何反应的,当然,此时输入什么都不会有反应。这是存在疑问的地方,希望知道的大神指点一二。
网上也提供了替代方案,比如利用第三方支持库SVox等。