文字转语音的奇妙之旅:利用Jacob与Windows语音库实现(仅限window系统)

在数字时代,信息的传递方式日益多样化,其中,将文字自动转化为语音并保存为文件的需求愈发普遍。无论是为了辅助视觉障碍者阅读,还是为了制作有声读物、自动化通知系统等,这一技术都展现出了巨大的应用潜力。近期,我踏上了一段探索之旅,旨在通过Java调用Windows内置的语音库,实现这一功能。在此过程中,我不仅学习到了如何利用Jacob库这一强大的桥梁,还深刻体会到了技术分享的温暖与力量。

缘起:一次需求的触发

故事的开始,源自我工作中遇到的一个具体需求——将大量文本快速转换为语音文件,以便在不同场景下使用。面对这一挑战,我首先想到的是利用现有的语音合成服务或API,但考虑到成本、定制性以及数据隐私等因素,我决定探索更为直接且成本效益高的解决方案:利用Windows平台自带的语音引擎。

探索:Jacob的魔力

在技术的海洋中,我偶然发现了Jacob(Java COM Bridge)这个宝藏。Jacob是一个开源库,它允许Java程序直接调用COM组件,从而轻松访问Windows系统级的功能,包括但不限于语音合成、文件操作等。这一发现让我眼前一亮,仿佛找到了一把打开Windows语音合成大门的钥匙。

实践:代码编织语音

在查阅了众多资料,并经过多次尝试后,我成功地将Jacob与Windows的SAPI(Speech Application Programming Interface)结合起来,实现了文字到语音的转换,并将结果保存为音频文件。以下是我实现这一功能的方法(基于Jacob 1.18版本):

一、pom.xml引入jar包依赖

<!-- https://mvnrepository.com/artifact/com.jacob/jacob 文字转语音 -->
<dependency>
  <groupId>com.hynnet</groupId>
  <artifactId>jacob</artifactId>
  <version>1.18</version>
</dependency>

二、把jacob-1.18-x64.dll文件复制到jdk安装位置的bin目录下。

不知道的话可以使用下列代码查看

public static void main(String[] args) {
        // 获取当前JVM的库路径
        String libraryPath = System.getProperty("java.library.path");
        // 打印库路径
        System.out.println("java.library.path: " + libraryPath);
}

三、在项目中测试运行。

(1)第一个demo:朗读文字

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
 
public class TestJacob {
    public static void main(String[] args) {
        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));
 
            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("警告,我也不知道怎么肥事"));
 
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sapo.safeRelease();
            sap.safeRelease();
        }
    }
 
}

(2)第二个demo:将文字转为音频文件

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
 
public class TestJacob {
 
    public static void main(String[] args) {
        ActiveXComponent ax = null;
 
        try {
            ax = new ActiveXComponent("Sapi.SpVoice");
            Dispatch spVoice = ax.getObject();
 
            ax = new ActiveXComponent("Sapi.SpFileStream");
            Dispatch spFileStream = ax.getObject();
 
            ax = new ActiveXComponent("Sapi.SpAudioFormat");
            Dispatch spAudioFormat = ax.getObject();
 
            //设置音频流格式
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
 
            //设置文件输出流格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            //调用输出 文件流打开方法,创建一个.wav文件
            Dispatch.call(spFileStream, "Open", new Variant("F:\\test.wav"), new Variant(3), new Variant(true));
            //设置声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            //设置音量 0到100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            //设置朗读速度
            Dispatch.put(spVoice, "Rate", new Variant(-2));
            //设置语音库
//            Dispatch.put(spVoice, "Voice", 1);
            //开始朗读
            Dispatch.call(spVoice, "Speak", new Variant("警告,我也不知道怎么肥事"));
            //关闭输出文件
            Dispatch.call(spFileStream, "Close");
            Dispatch.putRef(spVoice, "AudioOutputStream", null);
 
            spAudioFormat.safeRelease();
            spFileStream.safeRelease();
            spVoice.safeRelease();
            ax.safeRelease();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意:可能遇到的问题 

1、 运行的时候报 no jacob-1.18-x64 in java.library.path 错误,这个问题出现的话就是第2步有问题,还有要注意的是得注意报错提示的是什么版本,需要去下载对应的版本才行

2、报下面这个错误,一般就是电脑没有连音频设备,比如音响或者耳机。

com.jacob.com.ComFailException: Invoke of: Speak
Source:
Description: 没有注册类

3、下面这个错误的话,我也还不清楚是什么问题,但文件已经生成了 那么就可以忽略了,记得捕获异常就行。

com.jacob.com.ComFailException: Invoke of: AudioOutputStream
Source:
Description:

最后,谢谢其他大佬的分享

通过jacob实现文字转语音(附jacob-1.18-x64.dll下载地址)

java文字转语音播报功能的实现方法

Invoke of: Speak 问题

java使用com.jacob包 在Windows10开发环境运行正常,在Windows server 2008 抛出异常

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值