首页 > 其他分享 >Android TTS学习——保存对你的喜欢(转)

Android TTS学习——保存对你的喜欢(转)

时间:2023-08-09 11:01:30浏览次数:47  
标签:TTS 保存 private 音频文件 语音 Android null SD


一. 简单介绍

在上一篇里


我们介绍了TTS提供的接口 OnUtteranceCompletedListener 的使用,这个接口的作用是监听语音片段的朗读,并在语音片段朗读结束后调用其定义的回调函数,在回调函数里可以进行需要的操作。

在这一篇里我们介绍一下TTS提供的另一个有用的功能,把合成的语音以音频文件的形式保存在系统里,然后就可以直接用播放音频文件的方式来播放。

这个功能调用的函数为:

public int  synthesizeToFile ( String  text,  HashMap < String ,  String > params, String  filename)

第一个参数为要进行语音合成的文本;第二个参数我们在上一个Demo中有所介绍,是一个键值对形式的HashMap类型变量,可以设置语音片段的ID等;第三个参数为保存到系统中的文件名。

当你想和朋友分享一份精彩的文本合成语音后的效果时,你可以使用这个功能把它保存为音频文件发送给朋友,这样即使朋友的手机不具备TTS功能,也可以用播放音频的方式分享到;当你要对同一段较长的文本多次进行语音合成时,你可以把这段文本的语音保存为音频文件,然后使用时播放,这样会更省资源,运行速度更快,因为使用TTS是比较费资源的一个过程。因此我们会在某些场合用到这个功能。

下面我们就用这个功能完成一个Demo例子,当你害羞当面向她表白你对她的喜欢时,让Android帮你语音合成你想说的话,然后你就可以向她发送保存了对她喜欢的这个音频文件。

二. 实例开发

 

我们希望做的效果如下:

 

图1 实现效果图

 

第一个文本框里可以输入需要语音合成的文本,第二个文本框里输入要保存成的音频文件的文件名,点击第一个Speak 按钮你可以预听一下TTS 语音合成的效果,点击第二个Record 按钮,就会以音频文件的形式保存,然后就可以点击第三个Play

创建一个Android 工程,工程名为AndroidTTSDemoFourth ,其中SDK 版本需选择1.6

其中Main.xml

 


[xhtml] 
    view plain
    copy 
    
 
  
1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:orientation="vertical"  
4. android:layout_width="fill_parent"  
5. android:layout_height="fill_parent"  
6. >  
7. <EditText android:id="@+id/inputText"   
8. android:hint="Input the text here!"   
9. android:layout_width="fill_parent"   
10. android:layout_height="wrap_content">  
11. </EditText>  
12. <Button android:text="Speak"   
13. android:id="@+id/speakBtn"   
14. android:layout_width="wrap_content"   
15. android:layout_height="wrap_content"  
16. android:layout_gravity="center_horizontal"  
17. android:enabled="false"  
18. ></Button>  
19. <TextView android:id="@+id/filenameLabel"  
20. android:text="Save as:"  
21. android:layout_width="fill_parent"   
22. android:layout_height="wrap_content"                  
23. ></TextView>     
24. <EditText android:id="@+id/filenameText"  
25. android:hint="Input the saving file name here!"  
26. android:layout_width="fill_parent"   
27. android:layout_height="wrap_content">                  
28. ></EditText>  
29. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
30. android:orientation="horizontal"  
31. android:layout_width="fill_parent"  
32. android:layout_height="fill_parent"  
33. android:gravity="center_horizontal"  
34. >  
35. <Button android:id="@+id/recordBtn"  
36. android:text="Record"  
37. android:layout_width="wrap_content"   
38. android:layout_height="wrap_content"  
39. ></Button>  
40. <Button android:id="@+id/playBtn"  
41. android:text="Play"  
42. android:layout_width="wrap_content"   
43. android:layout_height="wrap_content"  
44. android:enabled="false"  
45. ></Button>  
46. </LinearLayout>                             
47. </LinearLayout>

 

 

Java

有了前面这些Demo 的实例开发,这个Demo

 


[java] 
    view plain
    copy 
    
 
  
1. public class AndroidTTSDemoFourth extends Activity implements OnInitListener{  
2. //实现初始接口  
3. /** Called when the activity is first created. */  
4. //定义变量  
5. private EditText inputText = null;  
6. private Button speakBtn = null;  
7. private EditText filenameText = null;  
8. private Button recordBtn = null;  
9. private Button playBtn = null;  
10. private TextToSpeech mTts;  
11. private static final String TAG = "TTS Demo";  
12. private static final String loveConfession = "jia jia, I love you. ";  
13. private String loveFileName = null;  
14. private File loveFile = null;  
15. private MediaPlayer player = null;  
16.       
17. @Override  
18. public void onCreate(Bundle savedInstanceState) {  
19. super.onCreate(savedInstanceState);  
20.         setContentView(R.layout.main);  
21. //创建TextToSpeech实例,初始化完成后会调用OnInitListener(第二个参数)的回调函数  
22. new TextToSpeech(this,  
23. this  // TextToSpeech.OnInitListener  
24.                 );  
25. //设置控件  
26.         inputText = (EditText)findViewById(R.id.inputText);  
27.         speakBtn = (Button)findViewById(R.id.speakBtn);  
28.         filenameText = (EditText)findViewById(R.id.filenameText);  
29.         recordBtn = (Button)findViewById(R.id.recordBtn);  
30.         playBtn = (Button)findViewById(R.id.playBtn);  
31.                 
32.         inputText.setText(loveConfession);    
33. "/sdcard/love.wav");  
34. new OnClickListener() {       
35. public void onClick(View v) {  
36. // TODO Auto-generated method stub  
37. //朗读输入框里的内容  
38. null);  
39.             }  
40.         });  
41. new OnClickListener() {              
42. @Override  
43. public void onClick(View v) {  
44. // TODO Auto-generated method stub  
45. //把TTS语音合成的结果保存为音频文件  
46.                 loveFileName = filenameText.getText().toString();  
47. new File(loveFileName);  
48. if(loveFile.exists())  
49.                 {  
50.                     loveFile.delete();  
51.                 }  
52. //把语音合成的结果保存到文件中  
53. if(TextToSpeech.SUCCESS == mTts.synthesizeToFile(inputText.getText().toString(), null, loveFileName))  
54.                 {  
55. "sound file created!", Toast.LENGTH_SHORT).show();  
56. true);  
57.                 }  
58. else  
59.                 {  
60. "failed to create sound file!", Toast.LENGTH_SHORT).show();  
61.                 }  
62.             }  
63.         });  
64. new OnClickListener() {            
65. @Override  
66. public void onClick(View v) {  
67. // TODO Auto-generated method stub  
68. //播放保存着的音频文件  
69. try  
70.                 {  
71. new MediaPlayer();  
72.                     player.setDataSource(loveFileName);  
73.                     player.prepare();  
74.                     player.start();  
75.                 }  
76. catch (Exception e) {  
77. // TODO: handle exception  
78. "failed to play sound file!", Toast.LENGTH_SHORT).show();  
79.                     e.printStackTrace();  
80.                 }  
81.             }  
82.         });  
83.     }  
84.       
85. public void onInit(int status) {  
86. // TODO Auto-generated method stub  
87. //TTS Engine初始化完成  
88. if(status == TextToSpeech.SUCCESS)  
89.         {  
90. int result = mTts.setLanguage(Locale.US);  
91. //设置发音语言  
92. if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)  
93. //判断语言是否可用  
94.             {  
95. "Language is not available");  
96. false);  
97.             }  
98. else  
99.             {  
100. true);  
101.             }  
102.         }  
103.     }  
104.       
105. @Override  
106. protected void onDestroy() {  
107. // TODO Auto-generated method stub  
108. //释放TTS的资源  
109. if(mTts != null)  
110.         {  
111.             mTts.stop();  
112.             mTts.shutdown();  
113.         }     
114. super.onDestroy();  
115.     }  
116. }

和TTS 相关的新的部分为recordBtn 的onClick 事件的处理,先根据指定的文件名创建一个File

mTts .synthesizeToFile( inputText .getText().toString(), null, loveFileName )

把文本框中的内容语音合成后保存到文件中。

另一个playBtn 的onClick 事件的处理,主要就是创建一个MediaPlayer

 

至此,这个Demo 就完成了,但是在运行前,需创建一个带SD 卡的AVD ,因为要往SD

图2 必须创建带SD 卡的AVD

 

同时还需在AndroidManifest.xml

< uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission >

接着就可以运行这个Demo 了,运行程序后在Eclipse 中切换到DDMS 视图,接着选择查看File Explorer ,我们看到在没有点击程序的Record 按钮进行语音合成到文件保存时,sdcard

 

图3 原始的SD

 

 

然后我们在程序中点击Record 按钮,让TTS 把语音合成到文件,合成成功的话会弹出“sound file created! ”的提示,并且Play 按钮变成可用。点击Play 按钮就会播放刚刚保存的音频文件,和点击第一个的Speak 按钮朗读的内容是一样的。这时,我们再来查看下SD 卡的目录,会发现多了一个文件:love.wav

 

图4 语音合成到文件后的SD

 

 

并且,我们还可以使用adb pull 命令把这个文件从SD 卡上提取出来,在CMD 窗口中运行adb pull ./sdcard/love.wav 就可以把SD

 

图5 提取SD

最后,也可以在电脑上播放记录了你对她的喜欢的这个音频文件了,或者也可以把这个文件发送给你喜欢的她。

 

注:文章参加“ 首届Google暑期大学生博客分享大赛——2010 Andriod篇”


一. 简单介绍

在上一篇里


我们介绍了TTS提供的接口 OnUtteranceCompletedListener 的使用,这个接口的作用是监听语音片段的朗读,并在语音片段朗读结束后调用其定义的回调函数,在回调函数里可以进行需要的操作。

在这一篇里我们介绍一下TTS提供的另一个有用的功能,把合成的语音以音频文件的形式保存在系统里,然后就可以直接用播放音频文件的方式来播放。

这个功能调用的函数为:

public int  synthesizeToFile ( String  text,  HashMap < String ,  String > params, String  filename)

第一个参数为要进行语音合成的文本;第二个参数我们在上一个Demo中有所介绍,是一个键值对形式的HashMap类型变量,可以设置语音片段的ID等;第三个参数为保存到系统中的文件名。

当你想和朋友分享一份精彩的文本合成语音后的效果时,你可以使用这个功能把它保存为音频文件发送给朋友,这样即使朋友的手机不具备TTS功能,也可以用播放音频的方式分享到;当你要对同一段较长的文本多次进行语音合成时,你可以把这段文本的语音保存为音频文件,然后使用时播放,这样会更省资源,运行速度更快,因为使用TTS是比较费资源的一个过程。因此我们会在某些场合用到这个功能。

下面我们就用这个功能完成一个Demo例子,当你害羞当面向她表白你对她的喜欢时,让Android帮你语音合成你想说的话,然后你就可以向她发送保存了对她喜欢的这个音频文件。

二. 实例开发

 

我们希望做的效果如下:

 

图1 实现效果图

 

第一个文本框里可以输入需要语音合成的文本,第二个文本框里输入要保存成的音频文件的文件名,点击第一个Speak 按钮你可以预听一下TTS 语音合成的效果,点击第二个Record 按钮,就会以音频文件的形式保存,然后就可以点击第三个Play

创建一个Android 工程,工程名为AndroidTTSDemoFourth ,其中SDK 版本需选择1.6

其中Main.xml

 


[xhtml] 
    view plain
    copy 
    
 
  
1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:orientation="vertical"  
4. android:layout_width="fill_parent"  
5. android:layout_height="fill_parent"  
6. >  
7. <EditText android:id="@+id/inputText"   
8. android:hint="Input the text here!"   
9. android:layout_width="fill_parent"   
10. android:layout_height="wrap_content">  
11. </EditText>  
12. <Button android:text="Speak"   
13. android:id="@+id/speakBtn"   
14. android:layout_width="wrap_content"   
15. android:layout_height="wrap_content"  
16. android:layout_gravity="center_horizontal"  
17. android:enabled="false"  
18. ></Button>  
19. <TextView android:id="@+id/filenameLabel"  
20. android:text="Save as:"  
21. android:layout_width="fill_parent"   
22. android:layout_height="wrap_content"                  
23. ></TextView>     
24. <EditText android:id="@+id/filenameText"  
25. android:hint="Input the saving file name here!"  
26. android:layout_width="fill_parent"   
27. android:layout_height="wrap_content">                  
28. ></EditText>  
29. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
30. android:orientation="horizontal"  
31. android:layout_width="fill_parent"  
32. android:layout_height="fill_parent"  
33. android:gravity="center_horizontal"  
34. >  
35. <Button android:id="@+id/recordBtn"  
36. android:text="Record"  
37. android:layout_width="wrap_content"   
38. android:layout_height="wrap_content"  
39. ></Button>  
40. <Button android:id="@+id/playBtn"  
41. android:text="Play"  
42. android:layout_width="wrap_content"   
43. android:layout_height="wrap_content"  
44. android:enabled="false"  
45. ></Button>  
46. </LinearLayout>                             
47. </LinearLayout>

 

 

Java

有了前面这些Demo 的实例开发,这个Demo

 


[java] 
    view plain
    copy 
    
 
  
1. public class AndroidTTSDemoFourth extends Activity implements OnInitListener{  
2. //实现初始接口  
3. /** Called when the activity is first created. */  
4. //定义变量  
5. private EditText inputText = null;  
6. private Button speakBtn = null;  
7. private EditText filenameText = null;  
8. private Button recordBtn = null;  
9. private Button playBtn = null;  
10. private TextToSpeech mTts;  
11. private static final String TAG = "TTS Demo";  
12. private static final String loveConfession = "jia jia, I love you. ";  
13. private String loveFileName = null;  
14. private File loveFile = null;  
15. private MediaPlayer player = null;  
16.       
17. @Override  
18. public void onCreate(Bundle savedInstanceState) {  
19. super.onCreate(savedInstanceState);  
20.         setContentView(R.layout.main);  
21. //创建TextToSpeech实例,初始化完成后会调用OnInitListener(第二个参数)的回调函数  
22. new TextToSpeech(this,  
23. this  // TextToSpeech.OnInitListener  
24.                 );  
25. //设置控件  
26.         inputText = (EditText)findViewById(R.id.inputText);  
27.         speakBtn = (Button)findViewById(R.id.speakBtn);  
28.         filenameText = (EditText)findViewById(R.id.filenameText);  
29.         recordBtn = (Button)findViewById(R.id.recordBtn);  
30.         playBtn = (Button)findViewById(R.id.playBtn);  
31.                 
32.         inputText.setText(loveConfession);    
33. "/sdcard/love.wav");  
34. new OnClickListener() {       
35. public void onClick(View v) {  
36. // TODO Auto-generated method stub  
37. //朗读输入框里的内容  
38. null);  
39.             }  
40.         });  
41. new OnClickListener() {              
42. @Override  
43. public void onClick(View v) {  
44. // TODO Auto-generated method stub  
45. //把TTS语音合成的结果保存为音频文件  
46.                 loveFileName = filenameText.getText().toString();  
47. new File(loveFileName);  
48. if(loveFile.exists())  
49.                 {  
50.                     loveFile.delete();  
51.                 }  
52. //把语音合成的结果保存到文件中  
53. if(TextToSpeech.SUCCESS == mTts.synthesizeToFile(inputText.getText().toString(), null, loveFileName))  
54.                 {  
55. "sound file created!", Toast.LENGTH_SHORT).show();  
56. true);  
57.                 }  
58. else  
59.                 {  
60. "failed to create sound file!", Toast.LENGTH_SHORT).show();  
61.                 }  
62.             }  
63.         });  
64. new OnClickListener() {            
65. @Override  
66. public void onClick(View v) {  
67. // TODO Auto-generated method stub  
68. //播放保存着的音频文件  
69. try  
70.                 {  
71. new MediaPlayer();  
72.                     player.setDataSource(loveFileName);  
73.                     player.prepare();  
74.                     player.start();  
75.                 }  
76. catch (Exception e) {  
77. // TODO: handle exception  
78. "failed to play sound file!", Toast.LENGTH_SHORT).show();  
79.                     e.printStackTrace();  
80.                 }  
81.             }  
82.         });  
83.     }  
84.       
85. public void onInit(int status) {  
86. // TODO Auto-generated method stub  
87. //TTS Engine初始化完成  
88. if(status == TextToSpeech.SUCCESS)  
89.         {  
90. int result = mTts.setLanguage(Locale.US);  
91. //设置发音语言  
92. if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)  
93. //判断语言是否可用  
94.             {  
95. "Language is not available");  
96. false);  
97.             }  
98. else  
99.             {  
100. true);  
101.             }  
102.         }  
103.     }  
104.       
105. @Override  
106. protected void onDestroy() {  
107. // TODO Auto-generated method stub  
108. //释放TTS的资源  
109. if(mTts != null)  
110.         {  
111.             mTts.stop();  
112.             mTts.shutdown();  
113.         }     
114. super.onDestroy();  
115.     }  
116. }

 

和TTS 相关的新的部分为recordBtn 的onClick 事件的处理,先根据指定的文件名创建一个File

mTts .synthesizeToFile( inputText .getText().toString(), null, loveFileName )

把文本框中的内容语音合成后保存到文件中。

另一个playBtn 的onClick 事件的处理,主要就是创建一个MediaPlayer

 

至此,这个Demo 就完成了,但是在运行前,需创建一个带SD 卡的AVD ,因为要往SD

图2 必须创建带SD 卡的AVD

 

同时还需在AndroidManifest.xml

< uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission >

接着就可以运行这个Demo 了,运行程序后在Eclipse 中切换到DDMS 视图,接着选择查看File Explorer ,我们看到在没有点击程序的Record 按钮进行语音合成到文件保存时,sdcard

 

图3 原始的SD

 

 

然后我们在程序中点击Record 按钮,让TTS 把语音合成到文件,合成成功的话会弹出“sound file created! ”的提示,并且Play 按钮变成可用。点击Play 按钮就会播放刚刚保存的音频文件,和点击第一个的Speak 按钮朗读的内容是一样的。这时,我们再来查看下SD 卡的目录,会发现多了一个文件:love.wav

 

图4 语音合成到文件后的SD

 

 

并且,我们还可以使用adb pull 命令把这个文件从SD 卡上提取出来,在CMD 窗口中运行adb pull ./sdcard/love.wav 就可以把SD

 

图5 提取SD

最后,也可以在电脑上播放记录了你对她的喜欢的这个音频文件了,或者也可以把这个文件发送给你喜欢的她。

 

注:文章参加“ 首届Google暑期大学生博客分享大赛——2010 Andriod篇”

标签:TTS,保存,private,音频文件,语音,Android,null,SD
From: https://blog.51cto.com/u_16034393/7016857

相关文章

  • Android13冻结进程分析:如何提高设备性能和用户体验
    Android13冻结进程分析:如何提高设备性能和用户体验本文介绍了Android13中的冻结进程功能,它是一种重要的资源管理策略,可以提高系统性能和稳定性,同时最大限度地节省设备的资源和电池消耗。文章讨论了如何合理分配资源,包括CPU、内存等,以提高设备性能和用户体验。此外,文章还提到了......
  • Android平台GB28181设备接入端如何实现多视频通道接入?
    技术背景我们在设计Android平台GB28181设备接入模块的时候,有这样的场景诉求,一个设备可能需要多个通道,常见的场景,比如车载终端,一台设备,可能需要接入多个摄像头,那么这台车载终端设备可以作为主设备,然后,主设备下,配置多个通道,听起来是不是有点儿类似于DVR或NVR?技术实现这里,我们说下,我们......
  • AutoX——当Android中clickable属性显示为false,实际可点击的布局如何处理
    前言最近在写一个关于某音的脚本,包含刷视频/点赞/收藏/分享/评论等一些列功能,借助于AutoX来实现,虽然我老早就买了AutoJsPro但是最新版本阉割的有点厉害。。。内容思索很简单就是,找到布局后,获取坐标信息,使用click去触发;varbtn=className("android.widget.TextView").t......
  • Android build.gradle 基本规则
    Androidbuild.gradle基本规则一个完整示例://此乃本脚本执行所需依赖,以下分别对应maven库和插件buildscript{repositories{//从AndroidStudio3.0后新增了google()配置,可以引用google上的开源项目google()mavenCentral()//......
  • 异常信息怎么转string保存入库
    首先说我们可能都会遇上这样的需求,进行trycatch捕获到异常,然后将异常信息存储到到DB中,而jdk自带的e.printStackTrace(),是直接将异常信息进行输出,没法进行保存。ExceptionUtils.getStackTrace(e)源自: org.apache.commons.lang3.exception;......
  • Android之Spinner用法,key/value模式
    参考:http://www.dedeyun.com/it/m/98498.htmlhttps://blog.csdn.net/myxiaoq/article/details/258696931.key、value类,需要重写toString()方法,返回text就是Spinner要显示的keypackagecom.jay.common;publicclassSpinnerData{privateStringvalue="";private......
  • Android开发 Jetpack compose LazyColumn 与 LazyRow、LazyVerticalGrid、LazyHorizon
    前言  此篇博客讲解LazyColumn与LazyRow、LazyVerticalGrid、LazyHorizontalGrid,在compose里LazyColumn与LazyRow与是用来延迟加载数据的,它对标原来xml里的ListView与RecyclerView。LazyColumn纵向列表效果图代码@ComposablefunAPage(){vallistData=remembe......
  • android 对话框AlertDialog。
    API:java.lang.Object ↳ android.app.AlertDialog.Builder使用AlertDialog.Builder创建对话框需要了解以下几个方法:setTitle:为对话框设置标题setIcon:为对话框设置图标setMessage:为对话框设置内容setView:给对话框设置自定义样式setItems:设置对话框要显示的一个list,一般用......
  • android 导出带数据库文件的APK
    http://www.ophonesdn.com/article/show/111技术文章基于OPhoneSDK1.5的英文电子词典的实现基于OPhoneSDK1.5的英文电子词典的实现OPhone平台开发,2009-12-0711:06:42标签:OPhoneSDK1.5英文词典英文词典是手机中经常使用的应用。因此,在本文将......
  • Android Service生命周期及用法!(转)
    AndroidService生命周期及用法!大家好,上一节我讲解了AndroidActivity的生命周期,这一节我将讲解一下Service,首先我们要知道Service具体是干什么的,什么时候用到?以及它的生命周期等。Service概念及用途:Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在......