本文主要介绍整个实现过程,一步一步跟着做,相信大家都可以完成的比我好。想要完整代码的可以跳过文章直接去文末获取,如果想要在本机上运行,请首先搭建好环境,如何搭建环境在项目的第二阶段里面。
这是Java实现语音朗读相对全面的一篇博客,汲取大家之精华,进行总结,内容可能稍多,但是仔细看下来,保证你能够准确无误地实现语音朗读,我是一个Java初学者,换位思考,理解这篇博客对于神通广大的你来说,不算什么!本文章主要用于学习交流,欢迎大家点赞留言。
Java、Jacob、SAPI、EXE、语音朗读
Windows、Java JDK/JRE 、sublime、eclipse
exe4j、PS、ICOFormat.8bi
(1) Jacob插件的使用。包括Sapi.SpVoice,ActiveXComponent,setProperty,Variant等的应用。
(2) GUI图形用户界面的使用。包括swing,awt,event包里的事件源、监视器、处理事件的接口等众多方法。
这一大条都是废话,大家可以自行忽略。
(1)在最初的准备阶段,我准备了好几种方案,并没有确定要用Java来实现项目,毕竟要以防万一。我首先准备了微软的Microsoft Speech SDK开发包,想借以C++来实现此项目,但是尝试之后以失败告终。
(2)上述过程失败之后,又尝试了与之类似的另一种方法,也是微软公司的,叫SAPI应用程序接口,不仅可以朗读语音,而且可以实现语音的识别和合成。但是很不幸,我又失败了。
(3)又尝试了微软的Visual Studio实现的MFC应用程序,具有可视化的界面,外表美观,可是失败了。
(4)最后敲定了是本学期我们刚刚学的Java,通过搜索资料得知,其jacob插件里的SAPI可实现语音朗读;与微软的SAPI的不同之处就是,Jacob里的SAPI我会用!那么这个项目也算是对新学知识的实践了,符合我们思政的鼓励思想。
(5)本来还想,为了功能的多样化,用Java实现知网论文的爬取或者时政新闻网站的数据爬取,方便用户查找资料并朗读。但是,事与愿违,尝试之后,代码根本跑不起来,错误连篇,漏洞百出。大概是因为这些网站的反爬虫机制做的太好了,所以就放弃了这个功能。
所有资料都可以去我个人主页的“我的收藏”“语音朗读”里面去找。
链接: 有关语音朗读资料.
最重要的环境就是Jacob搭建了。这个插件可以说是Java JDK/JRE的一个包,但是在最初安装JDK/JRE时是没有这个包的,所以需要自己配置。
具体配置过程可以参考以下网址或者看我精简后的配置过程:
链接: Jacob配置方法.
链接: Jacob介绍.
目前最新版本1.18jacob-1.18下载,主要有三个文件:
链接: Jacob下载链接.
下载后解压得到
jacob.jar
jacob-1.18-x64.dll
jacob-1.18-x86.dll
dll文件有俩,对应windows 64 和32
1.将jacob-1.18-x64.dll放到64位的java的jdk或jre下的bin目录下
如果是32位系统就将jacob-1.18-x86.dll放到32位的jdk或jre下的bin目录下
2.将要操作的dll 文件放到相应的系统目录下
32位dll放到 C:\Windows\System32 目录下
64位dll放到 C:\Windows\SysWOW64 目录下
注:
搭建环境可能影响因素很多,我几次试错才成功。如果搭建错误,不妨试试把这些文件在JDK和JRE的bin目录下都放置一份。
既然基本环境已经搭建成功,那么就可以学习使用插件和尝试用它编写代码了。Jacob包内的内容庞杂,Jacob是Java和com组件之间的桥梁,Jacob包里的Jacob.dll就是com组件,com组件的功能就是实现单一功能,就像用代码操控Word一样,我们不需要具体去实现它,而是去学习怎样去使用它。
具体方法就是对Jacob SAPI的应用。
主要是利用Java GUI程序,运用其中的awt、event和swing包。这些都是Java环境自带的,无须额外下载。
实现后的界面:
Java程序可以生成JAR包,然后由exe4j这个程序,通过设置一些版本号、作者签名来增加安全性后,会自动融合代码涉及的环境,生成EXE程序,就可以移植到别的普通电脑运行了。
//阅读文本文件
ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
//输入文件
//
labelShow.setText("文件路径需要用“ / ”间隔");
File srcFile = new File(str);
//使用包装字符流读取文件
/*
* BufferedReader br = new BufferedReader(new FileReader(srcFile));
* String content = br.readLine();
*/
try {
BufferedReader br = new BufferedReader(new FileReader(srcFile));
String content = br.readLine();
// 音量 0-100
sap.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
sap.setProperty("Rate", new Variant(2));
// 获取执行对象
Dispatch sapo = sap.getObject();
// 执行朗读
while (content != null) {
Dispatch.call(sapo, "Speak", new Variant(content));
content = br.readLine();
}
Dispatch.call(sapo, "Speak", new Variant("朗读完了,休息一下吧"));
labelShow.setText("朗读结束...");
// 关闭执行对象
br.close();
sapo.safeRelease();
} catch (Exception j) {
j.printStackTrace();
} finally {
// 关闭应用程序连接
sap.safeRelease();
}
}
参考如下网址
链接: Java实现朗读文本文件.
链接: Java实现对输入的语句进行朗读.
制作方法可参考如下链接(实测可用)
链接: Java的JAR包导出和EXE程序制作1.
链接: EXE程序制作2.
完整代码和程序下载地址:
可能需要积分,如果实在没有积分,可私聊我,我单独发给你。
链接: eclipse项目完整代码+EXE程序下载.
1.要选择功能,之后点击“开始阅读”,才能成功朗读。
2.如果阅读文本文件时,出现朗读乱码的情况,是因为记事本文件使用的是UTF_8编码,而这个程序还是GBK编码,可以在记事本的编辑—文本中更改为GBK格式。具体方法可以到网上去搜。
3.如果JAR包可以执行,而EXE程序不可执行,大概率是因为EXE程序制作过程出错,根据步骤,慢慢再来一遍就可以。
注:包含几个Java文件,拷贝后运行时要注意。
//主类InputShow.java
public class InputShow {
public static void main(String[] args) {
// TODO Auto-generated method stub
WindowsEvent show = new WindowsEvent ();
PoliceListener police = new PoliceListener();
show.setMyCommandListener(police);
show.setTitle("语音朗读");
show.setBounds(100,100,500,650);
}
}
//窗口类WindowsEvent.java
import java.awt.*;
import javax.swing.*;
public class WindowsEvent extends JFrame{
private static final long serialVersionUID = -5692167079052370018L;
JTextArea textInput;
//JScrollPane scroll;;
JButton button;
JLabel labelShow;
JRadioButton radioWords;
JRadioButton radioTxt;
ButtonGroup group;
MycommandListener listener;
public WindowsEvent() {
//构造函数
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
//初始化函数
//setLayout(new GridLayout(4,1));//设置布局
setLayout(new FlowLayout());
//setLayout(null);
//设置四个面板
//显示文本区
JPanel panelText = new JPanel();
panelText.setSize(500, 350);
//panelText.setLayout(null);
add(panelText,BorderLayout.NORTH);
//显示按钮面板
JPanel panelButton = new JPanel();
panelButton.setSize(500, 50);
add(panelButton,BorderLayout.SOUTH);
//显示选择面板
JPanel panelChoice = new JPanel();
panelChoice.setSize(500,50);
add(panelChoice,BorderLayout.CENTER);
//显示提示面板
JPanel panelHint = new JPanel();
panelHint.setSize(500, 50);
add(panelHint);
//JTextArea()设置文本区及格式
textInput = new JTextArea(19,47) ;//分配文本区域
textInput.setLineWrap(true);//随着文本区大小换行
//JScrollPane scrollpane = new JScrollPane(textInput);
//textInput = new JTextField(10);
textInput.setFont(new Font("宋体", Font.PLAIN, 20));// 设置此标签的字体。
panelText.add(new JScrollPane(textInput));
//选择区
group = new ButtonGroup();
radioWords = new JRadioButton("输入语段朗读");
radioWords.setFont(new Font("宋体", Font.PLAIN, 20));
radioTxt = new JRadioButton("嵌入txt文件朗读");
radioTxt.setFont(new Font("宋体", Font.PLAIN, 20));
group.add(radioWords);
group.add(radioTxt);
panelChoice.add(radioWords);
panelChoice.add(radioTxt);
add(panelChoice);
//按钮区
button = new JButton("开始朗读");//添加按钮
panelButton.add(button);
button.setFont(new Font("宋体", Font.PLAIN, 20));
add(panelButton);
//标签区
labelShow = new JLabel();//添加提示标签
labelShow.setFont(new Font("宋体", Font.BOLD, 25));// 设置此标签的字体。
panelHint.add(labelShow,BorderLayout.SOUTH);
add(panelHint);
}
void setMyCommandListener(MycommandListener listener) {
//安装监视器函数
this.listener = listener;
listener.setJButton(button);
listener.setJTextArea(textInput);
listener.setJLabel(labelShow);
listener.setJRadioButton(radioWords);
//listener.setJRadioButton(radioTxt);
//添加监视器
button.addActionListener(listener);
//button是事件源,listener是监视器
}
}
//监视器接口类 MycommandListener.java
import java.awt.event.*;
import javax.swing.*;
public interface MycommandListener extends ActionListener{
//子接口
//实现文本区域和按键的监视器
public void setJTextArea(JTextArea area);
public void setJButton(JButton button);
public void setJLabel(JLabel label);
public void setJRadioButton(JRadioButton radioButton);
}
//监视器实现类,核心代码块 PoliceListener.java
import java.awt.event.*;
import javax.swing.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import java.io.*;
public class PoliceListener implements MycommandListener{
JTextArea textArea;
//JScrollPane textArea;
JButton readButton;
JLabel labelShow;
JRadioButton radioButton;
public void setJTextArea(JTextArea area) {
textArea = area;
}
public void setJButton(JButton button) {
readButton = button;
}
public void setJLabel(JLabel label) {
labelShow = label;
}
public void setJRadioButton(JRadioButton radioButton) {
this.radioButton=radioButton;
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
labelShow.setText(" ");
String str = textArea.getText();
if(radioButton.isSelected()) {
//阅读输入字段
ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
//获取朗读对象
Dispatch sapo = sap.getObject();
try {
// 音量 0-100
sap.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
sap.setProperty("Rate", new Variant(2));
// 执行朗读
Dispatch.call(sapo, "Speak", new Variant(str));
Dispatch.call(sapo, "Speak", new Variant("朗读完了,休息一下吧"));
labelShow.setText("朗读结束...");
} catch (Exception i) {
i.printStackTrace();
} finally {
sapo.safeRelease();//关闭执行对象
sap.safeRelease();//关闭应用程序链接
}
}else {
//阅读文本文件
ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
//输入文件
//
labelShow.setText("文件路径需要用“ / ”间隔");
File srcFile = new File(str);
try {
BufferedReader br = new BufferedReader(new FileReader(srcFile));
String content = br.readLine();
// 音量 0-100
sap.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
sap.setProperty("Rate", new Variant(2));
// 获取执行对象
Dispatch sapo = sap.getObject();
// 执行朗读
while (content != null) {
Dispatch.call(sapo, "Speak", new Variant(content));
content = br.readLine();
}
Dispatch.call(sapo, "Speak", new Variant("朗读完了,休息一下吧"));
labelShow.setText("朗读结束...");
// 关闭执行对象
br.close();
sapo.safeRelease();
} catch (Exception j) {
j.printStackTrace();
} finally {
// 关闭应用程序连接
sap.safeRelease();
}
}
}
}