jacob和百度语音合成 播报的实现形式

有个语音播报的需求,这些日子查了一些资料,在这里总结一下,一些工具类和文件我已经放到了下载路径上,下面提供

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

猜你喜欢

转载自blog.csdn.net/Goligory/article/details/81215414