有个语音播报的需求,这些日子查了一些资料,在这里总结一下,一些工具类和文件我已经放到了下载路径上,下面提供
1,jacob
引入maven
<!-- https://mvnrepository.com/artifact/net.sf.jacob-project/jacob -->
<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.14.3</version>
</dependency>
将jacob-1.14.3-x64放在jdk的bin中,和C:\WINDOWS\System32中,注意放入的jacob和maven下载版本要一致
实现代码如下
public static void stratVoice(String content, int type) {
ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
Dispatch sapo = sap.getObject();
if (type == 0) {
try {
// 音量 0-100
sap.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
sap.setProperty("Rate", new Variant(0));
Variant defalutVoice = sap.getProperty("Voice");
Dispatch dispdefaultVoice = defalutVoice.toDispatch();
Variant allVoices = Dispatch.call(sapo, "GetVoices");
Dispatch dispVoices = allVoices.toDispatch();
Dispatch setvoice = Dispatch.call(dispVoices, "Item",
new Variant(1)).toDispatch();
ActiveXComponent voiceActivex = new ActiveXComponent(
dispdefaultVoice);
ActiveXComponent setvoiceActivex = new ActiveXComponent(
setvoice);
Variant item = Dispatch.call(setvoiceActivex, "GetDescription");
// 执行朗读
Dispatch.call(sapo, "Speak", new Variant(content));
} catch (Exception e) {
log.info("错误:", e);
e.printStackTrace();
} finally {
sapo.safeRelease();
sap.safeRelease();
}
} else {
// 停止
try {
Dispatch.call(sapo, "Speak", new Variant(content), new Variant(
2));
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
引用
public static void main(String[] args) {
VoiceUtil.stratVoice("桃之夭夭,灼灼其华。之子于归,宜其室家。\n" +
"桃之夭夭,有蕡其实。之子于归,宜其家室。\n" +
"桃之夭夭,其叶蓁蓁。之子于归,宜其家人", 0);
}
可以自己玩一下参数
2,百度语音合成(服务端播报)
http://ai.baidu.com/docs#/ASR-Online-Java-SDK/top 这是官网
可以先看下文档了解下,下面先引maven
<!-- https://mvnrepository.com/artifact/com.baidu.aip/java-sdk -->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.3.2</version>
</dependency>
这是主要代码,具体去链接下载即可
public String voiceRun(HttpServletRequest request){
try {
TokenHolder holder = new TokenHolder(appKey, secretKey, TokenHolder.ASR_SCOPE);
holder.refresh();
String token = holder.getToken();
// 此处2次urlencode, 确保特殊字符被正确编码
String params = "tex=" + ConnUtil.urlEncode(ConnUtil.urlEncode(text));
params += "&per=" + per;
params += "&spd=" + spd;
params += "&pit=" + pit;
params += "&vol=" + vol;
params += "&cuid=" + cuid;
params += "&tok=" + token;
params += "&aue=" + aue;
params += "&lan=zh&ctp=1";
log.info("反馈请带上此url,浏览器上可以测试:{}", url + "?" + params); // 反馈请带上此url,浏览器上可以测试
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setConnectTimeout(5000);
PrintWriter printWriter = new PrintWriter(conn.getOutputStream());
printWriter.write(params);
printWriter.close();
String contentType = conn.getContentType();
if (contentType.contains("audio/")) {
byte[] bytes = ConnUtil.getResponseBytes(conn);
String format = getFormat(aue);
// 第二种:获取项目路径
File directory = new File("");// 参数为空
String path = request.getSession().getServletContext().getRealPath("/");
System.out.println(path);
File file = new File(path + "result." + format); // 打开mp3文件即可播放
FileOutputStream os = new FileOutputStream(file);
os.write(bytes);
os.close();
log.info("存储路径:{}", file.getAbsolutePath());
// boolean ret = voiceStart(format);
// log.info("播放结果:{}", ret);
return "success";
} else {
System.err.println("ERROR: content-type= " + contentType);
String res = ConnUtil.getResponseString(conn);
System.err.println(res);
return null;
}
}catch (Exception e){
return null;
}
}
request.getSession().getServletContext().getRealPath("/");这个获取的是项目根目录,是wav文件的存放路径,等会播报会用到
播放wav
public static boolean voiceStart(String format) {
try {
log.info("播放开始,{}", System.getProperty("user.dir"));
// 1.wav 文件放在java project 下面 即可播放
FileInputStream fileau = new FileInputStream(
System.getProperty("user.dir") + "\\result." + format);
AudioStream as = null;
as = new AudioStream(fileau);
AudioPlayer.player.start(as);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
这里面播报用到的路径我没改,不应该用System.getProperty("user.dir")这个获取,我当时就没获取到这个路径,也应该用刚才存路径的那个request.getSession().getServletContext().getRealPath("/"),如果你本地main测试可以先写死
wav文件保留30天,30天后失效,所以播报可以放在外面,30天内都可以直接调用播报即可,不用重复生成,还要想办法如何在30天内最低会调用一次voiceRun合成语音接口,使wav文件不至于失效播报不出来,这个就自己想办法吧
这个在本地是可以播报的,如果在服务器上则需要设置下服务器的声音 可以看下这个:https://jingyan.baidu.com/article/c1a3101e72939bde656deb1c.html
因为是服务器端播报,如果想听到声音要远程连接,如果关闭了连接就听不到了,这个如果有大神知道如何解决这个问题请留言告知
3,百度语音合成:客户端播报
客户端可以先用上面已用voiceRun生成wav文件,然后定义一个div
<div id="emb"></div>
用js实现业务调用
function myrefresh() {
$.ajax({
type: "GET",
url: "/server/status",
dataType: "json",
data: "",
success: function (data) {
var res = data.res;
if (res != 0) {
//根据业务
var data = "<embed id=\"wavFileId\"\n" +
" src=\"/YQStore/result.wav\"\n" +
" width=\"0\"\n" +
" height=\"0\"\n" +
" loop=\"false\"\n" +
" autostart=\"false\">\n" +
"</embed>";
$('#emb').html(data);
console.log("语音提醒")
try {
var node = document.getElementById('wavFileId');
if(node!=null){
node.Play();
}
} catch (err) {
console.log("err->" + err)
}
}
setTimeout('myrefresh()', 5000); //指定5秒刷新一次
},
error: function () {
setTimeout('myrefresh()', 5000); //指定5秒刷新一次
}
});
}
setTimeout('myrefresh()', 5000);
5s钟刷新一次根据业务进行播报,src就是wav后端存的路径
这样就可以实现在本地可以听到语音播报了,但是有个缺点就是如果不在当前页面就会听不到声音,不过可以将页面单独拉出来放在后面,再操作自己的网页就不影响播报了,如果有大神有更好的办法望告知,谢谢
下载地址:https://download.csdn.net/download/goligory/10565209