注意
本文主要介绍整个实现过程,一步一步跟着做,相信大家都可以完成的比我好。想要完整代码的可以跳过文章直接去文末获取,如果想要在本机上运行,请首先搭建好环境,如何搭建环境在项目的第二阶段里面。
概述
这是Java实现语音朗读相对全面的一篇博客,汲取大家之精华,进行总结,内容可能稍多,但是仔细看下来,保证你能够准确无误地实现语音朗读,我是一个Java初学者,换位思考,理解这篇博客对于神通广大的你来说,不算什么!本文章主要用于学习交流,欢迎大家点赞留言。
关键词
主要环境
Windows、Java JDK/JRE 、sublime、eclipse
exe4j、PS、ICOFormat.8bi
主要知识点
(1) Jacob插件的使用。包括Sapi.SpVoice,ActiveXComponent,setProperty,Variant等的应用。
(2) GUI图形用户界面的使用。包括swing,awt,event包里的事件源、监视器、处理事件的接口等众多方法。
项目主要分为六大阶段(一、到六、)
-
注意
-
概述
-
关键词
-
主要环境
-
主要知识点
-
一、广泛搜集资料,学习专业知识,了解主体框架,打牢基础;
-
二、尝试已经获得的资料,寻找突破口,确定发展方向;
-
三、在已有的方向上开始动手实践,试错调试,完成核心代码;
-
四、编辑可视化界面,为项目提供良好的视觉体验;
-
五、完善代码,生成EXE程序,而后增加安全性和可移植性;
-
六、上传有关资源,撰写项目报告书,方便交流沟通和完善改进。
-
可能存在的问题
-
缺陷或改进
-
完整代码
一、广泛搜集资料,学习专业知识,了解主体框架,打牢基础;
这一大条都是废话,大家可以自行忽略。
(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.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包内的内容庞杂,Jacob是Java和com组件之间的桥梁,Jacob包里的Jacob.dll就是com组件,com组件的功能就是实现单一功能,就像用代码操控Word一样,我们不需要具体去实现它,而是去学习怎样去使用它。
三、在已有的方向上开始动手实践,试错调试,完成核心代码;
具体方法就是对Jacob SAPI的应用。
四、编辑可视化界面,为项目提供良好的视觉体验;
主要是利用Java GUI程序,运用其中的awt、event和swing包。这些都是Java环境自带的,无须额外下载。
实现后的界面:
五、完善代码,生成EXE程序,而后增加安全性和可移植性;
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();
}
EXE程序制作方法
制作方法可参考如下链接(实测可用)
链接: Java的JAR包导出和EXE程序制作1.
链接: EXE程序制作2.
制作完成后的EXE程序:
可能存在的问题
1.要选择功能,之后点击“开始阅读”,才能成功朗读。
2.如果阅读文本文件时,出现朗读乱码的情况,是因为记事本文件使用的是UTF_8编码,而这个程序还是GBK编码,可以在记事本的编辑—文本中更改为GBK格式。具体方法可以到网上去搜。
3.如果JAR包可以执行,而EXE程序不可执行,大概率是因为EXE程序制作过程出错,根据步骤,慢慢再来一遍就可以。
缺陷或改进
-
界面布局单一不美观
-
任务朗读没有感情、遇到特殊字符不知变通
-
功能单一,不能像小爱和小娜那样什么都会
-
只能在Windows平台下,平台单一
-
缺少选取文件的功能,只能手动输入文件路径(如果你会Java文本对话框这个问题就轻而易举了)
-
不能中断,只能关闭程序来强行中断
-
没有调节音量大小的功能
完整代码
注:包含几个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();
java添加数据库数据 java增加数据库
java实现数据库的增删改查 DBUtil工具类 package com.zr;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.awt.geom.AreaOp;import java.sql.*;
public class DBUtil {
public static Connectio
Java 多个word合并 java合并pdf文件最简单的方法
多个PDF文件合并成一个PDF文件主要用到了pdfbox.jar和commons-logging.jar ,如图:源码如下:package pdfUtity;
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.util.PDFMergerUtility; public class PdfChang
python矩阵统计相同个数 python 矩阵计算
用sympy进行矩阵计算的基本操作首先创建矩阵基本操作,首先构造下图中的矩阵,特别注意:一维矩阵的建立格式。from sympy import *
import math
import numpy as np
a = Matrix([[3,5],[-1,1],[0,5]])
print(a)
b = Matrix([1,2,3])#三行一列
print(b.shape)
c = Matri
2.分布式医疗云平台(项目功能简介截图)【系统管理(科室管理、用户管理、角色管理、菜单管理 、字典管理、通知公告管理 、检查费用设置、挂号费用设置 )】】(四)-全面详解(学习总结---从入门到深化)
3.docker安装mysql
4.基于安全产品DNS隧道流量分析
5.Isito 入门:为什么学 Istio、Istio 是什么