【离线文本转语音文件】java spring boot jacob实现文字转语音文件,离线文本转化语音,中英文生成语音,文字朗读,中文生成声音,文字生成声音文件,文字转语音文件,文字变声音。

1.实现效果如下:

输入文字(支持中英文),点击转换生成***.wav文件,点击下载到本地就可。

 生成后的音频文件播放,时长1分8秒

2.实现代码:

         这次采用jacob实现,相比百度AI需要联网,本项目定位内网环境实现。所以最终采jacob。

1.环境配置:

本次采用版本jacob-1.19,我们需要下载jacob.jar和dll

下载地址:jacob语音生成文件,jacobx64.dll和jacob.jar为1.9-Java文档类资源-CSDN下载

官网地址:JACOB - Java COM Bridge download | SourceForge.net

下载后得到两个文件:

jacob.dll:配置到jdk环境中

jacob.jar:放入到项目中并配置下pox和Idea 的dependencies下

第一步

jacob.dll放入:C:\Program Files\Java\jdk1.8.0_121\jre\bin

 第二步:

        1.首先有一个spring boot项目,没有就搭建一个

        2.把jacob放到项目resources>lib目录下

         3.在pom.xml文件添加依赖:

 <!--添加本地的jacob.jar包-->
        <dependency>
            <groupId>com.jacob</groupId>
            <artifactId>jacob</artifactId>
            <version>1.19</version>
            <!--system使用本地jar包-->
            <scope>system</scope>
            <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>
        </dependency>

4.在idea下的项目中添加依赖包,

 5.这样环境就搭建完成。

2.编码:

核心代码,这样就可以输入文字,生成音频文件保存到本地目录中,然后下载音频文件就只需要读取文件就可以。

 //输入文本内容,生成文件地址 text为输入的文本信息
    public void audioFile(String text){
        try {
            
            //jacob.dll没成功安装,执行这一步会出错
            //构建音频格式 调用注册表应用
            Dispatch spAudioFormat = new ActiveXComponent("Sapi.SpAudioFormat").getObject();
            //音频文件输出流
            Dispatch spFileStream = new ActiveXComponent("Sapi.SpFileStream").getObject();
            //构建音频对象
            Dispatch spVoice =  new ActiveXComponent("Sapi.SpVoice").getObject();

            //设置spAudioFormat音频流格式类型22
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            //设置spFileStream文件输出流的音频格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            
            //设置spFileStream文件输出流参数地址等 
            Dispatch.call(spFileStream, "Open", new Variant("D:\speech\48641486.wav"), new Variant(3), new Variant(true));
            //设置spVoice声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            //设置spVoice声音对象的音量大小100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            //设置spVoice声音对象的速度 0为正常速度,范围【..-2 -1 0 1 2..】
            Dispatch.put(spVoice, "Rate", new Variant(0));
            //设置spVoice声音对象中的文本内容
            Dispatch.call(spVoice, "Speak", new Variant(text));
            //关闭spFileStream输出文件
            Dispatch.call(spFileStream, "Close");

            //释放资源
            spVoice.safeRelease();
            spAudioFormat.safeRelease();
            spFileStream.safeRelease();

        }catch (Exception e){
            System.out.println(e.getMessage());
        }
       
    }

3.其他业务代码:非核心

下面就贴上完整的项目代码和配置文件

1.项目结构:

 主要就几个文件:HomeController、TextToSpeechFileService、index.html、pom.xml

2.pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>text_speech</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>text_speech</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.5.0</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--添加本地的jacob.jar包-->
        <dependency>
            <groupId>com.jacob</groupId>
            <artifactId>jacob</artifactId>
            <version>1.19</version>
            <!--system使用本地jar包-->
            <scope>system</scope>
            <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>
        </dependency>


    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.0</version>
                <configuration>
                    <mainClass>com.example.text_speech.TextSpeechApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3.index.xml

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>文字转语音</title>
    <link rel="shortcut icon" href="https://pic.onlinewebfonts.com/svg/img_196224.png">
    <link th:href="@{/plugins/layui/src/css/layui.css}" type="text/css" rel="stylesheet"/>
    <script th:inline="javascript">
        let ctx = /*[[@{/}]]*/ '';
    </script>
</head>
<body>
    <fieldset class="layui-elem-field layui-field-title" style="margin-top: 80px;">
        <legend>文字转音频文件</legend>
    </fieldset>

    <div class="layui-bg-gray" style="padding: 30px;">
        <div class="layui-row layui-col-space15">
            <div class="layui-col-md6">
                <!--一行内容块-->
                <div class="layui-form-item layui-form-text layui-panel"  >
                    <textarea placeholder="请输入内容,支持中英文字。" id="textContent" class="layui-textarea" style="height: 400px"></textarea>
                </div>
            </div>
            <div class="layui-col-md6 ">
                <div class="layui-form-item "style="width: 100px">
                    <button  style="margin-top: 100px;" class="layui-btn" onclick="getAudioFile()" >生成音频文件</button>
                </div>

                <div class="layui-panel" style="width: 400px;margin-left: 200px;top: -50px;height: 200px" >
                    <div id="noFile" style="margin: 20px">
                        等待生成文件。
                    </div>
                    <div id="existFile" hidden>
                        <h3 style="text-align: center">音频文件已经生成</h3>
                        <div style="margin: 20px" >
                            <div>文件名称:<span id="fileName"></span></div>
                            <div>文件格式:<span id="fileFormat"></span></div>
                            <div>创建时间:<span id="fileDate"></span></div>
                        </div>
                        <button  style="margin: 20px;margin-left: 35%" class="layui-btn" onclick="downFile()">下载文件</button>
                    </div>
                </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script th:src="@{/plugins/jquery/jquery-1.12.0.min.js}" type="text/javascript"></script>
<script th:src="@{/plugins/layui/src/layui.js}" type="text/javascript"></script>
<script type="text/javascript">

    /*文字转换*/
    function getAudioFile(){
        let loading = layer.load('Loading...', {
            shade: [0]
        });
        let text = $("#textContent").val();
        $.post("./tts",{"textContent":text},function (data) {
            layer.close(loading);
            if (data.code==="1"){
                $("#existFile").show();
                $("#noFile").hide();
                $("#fileName").html(data.name);
                $("#fileFormat").html(data.format);
                $("#fileDate").html(data.date);
            }else {
                $("#existFile").hide();
                $("#noFile").show();
                $("#noFile").html("文件生成发生错误。请检查输入内容。保证只有标准的标点符号和文字。");
            }
        })
    }

    /*下载文件*/
    function downFile(){
        window.open("./downFile?fileName="+$("#fileName").html(), "_blank");
    }

</script>
</html>

3.HomeController 

package com.example.text_speech.controller;

import com.example.text_speech.service.TextSpeechService;
import com.example.text_speech.service.TextToSpeechFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;


@Controller
public class HomeController {
    
    @Autowired
    private TextToSpeechFileService textToSpeechFileService;
    


    /***
     * @Author: LiaoJJ
     * @Description:主页
     */
    @RequestMapping({"/index","/",""})
    public ModelAndView index(){
        return new ModelAndView("index");
    }


    /***
     * @Author: admin
     * @Description: 文本转语音
     */
    @RequestMapping("/tts")
    @ResponseBody
    public HashMap<String,String> textTransformAudio(String textContent){
       return textToSpeechFileService.audioFile(textContent);
    }

    /***
     * @Author: admin
     * @Description: 下载文件
     */
    @RequestMapping("/downFile")
    @ResponseBody
    public void down(String fileName, HttpServletResponse response){
        textToSpeechFileService.down(fileName,response);
    }


}

 4.TextToSpeechFileService

package com.example.text_speech.service;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/***
 * @Author: LiaoJJ
 * @Date: 2022/10/12
 * @Description:文字转语音文件
 */
@Service
@ComponentScan
public class TextToSpeechFileService {

    //语音文件生成的临时文件
    @Value("${filePath}")
    private String path;

    //输入文本内容,生成文件地址
    public HashMap<String,String> audioFile(String text){
        HashMap<String , String> map = new HashMap<>();
        try {
            //构建音频格式 调用注册表应用
            Dispatch spAudioFormat = new ActiveXComponent("Sapi.SpAudioFormat").getObject();
            //音频文件输出流
            Dispatch spFileStream = new ActiveXComponent("Sapi.SpFileStream").getObject();
            //构建音频对象
            Dispatch spVoice =  new ActiveXComponent("Sapi.SpVoice").getObject();

            //设置spAudioFormat音频流格式类型22
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            //设置spFileStream文件输出流的音频格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            //随机uuid
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            String filePath = path + uuid + ".wav";
            //设置spFileStream文件输出流参数地址等
            Dispatch.call(spFileStream, "Open", new Variant(filePath), new Variant(3), new Variant(true));
            //设置spVoice声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            //设置spVoice声音对象的音量大小100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            //设置spVoice声音对象的速度 0为正常速度,范围【..-2 -1 0 1 2..】
            Dispatch.put(spVoice, "Rate", new Variant(0));
            //设置spVoice声音对象中的文本内容
            Dispatch.call(spVoice, "Speak", new Variant(text));
            //关闭spFileStream输出文件
            Dispatch.call(spFileStream, "Close");

            //释放资源
            spVoice.safeRelease();
            spAudioFormat.safeRelease();
            spFileStream.safeRelease();

            map.put("code","1");
            map.put("name",uuid + ".wav");
            map.put("format","wav");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            map.put("date",sdf.format(new Date()));
        }catch (Exception e){
            System.out.println(e.getMessage());
            map.put("code","0");
        }
        return map;
    }

    /***
     * @Author: LiaoJJ
     * @Description: 下载文件
     */
    public void down(String fileName, HttpServletResponse response) {
        try {
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
            response.addHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes(),"utf-8"));
            //获取文件输入流
            InputStream in = new FileInputStream(path+fileName);
            int len = 0;
            byte[] buffer = new byte[1024];
            OutputStream out = response.getOutputStream();
            while ((len = in.read(buffer)) > 0) {
                //将缓冲区的数据输出到客户端浏览器
                out.write(buffer,0,len);
            }
            in.close();
        }catch (Exception e){
            e.getMessage();
            System.out.println("文件下载失败");
        }
    }

}

5.application.yml

# 应用名称
spring:
  application:
    name: text_speech
  devtools:
    restart:
      enabled: true
      additional-paths: resources/**,static/**,templates/**
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    cache: false  # 开启模板缓存
    encoding: UTF-8
    servlet:
      content-type: text/html
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  resources:
    add-mappings: true
    #静态资源访问路径
    static-locations: classpath:/static,classpath:/templates/,file:${config.file.root}

# 应用服务 WEB 访问端口
server:
  port: 8080

#配置本地临时文件夹
filePath: D:\speech\

通过上面的几个文件代码,就可以实现文章前面web页面的效果了。

本文章只是一个demo演示。应用到具体业务中还需要做一些修改。

如果其中存在什么问题回复到评论区,及时修改。感谢阅览。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值