Jacob 文字转语音
1.导入依赖
<dependency>
<groupId>com.hynnet</groupId>
<artifactId>jacob</artifactId>
<version>1.18</version>
</dependency>
2.下载 jacob.dll 文件,将 dll 拷贝到 jdk 的 bin 目录
3.工具类
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import lombok.extern.slf4j.Slf4j;
/**
* 语音工具
*
* @author dev
*/
@Slf4j
public class VoiceUtil {
/**
* 阅读文本并输出文件
*
* @param text 需要阅读的文本
* @param speed 阅读速度
* @param output 输出文件
*/
public static void speak(String text, Integer speed, String output) {
ActiveXComponent voiceComponent = null;
ActiveXComponent fileStreamComponent = null;
ActiveXComponent audioComponent = null;
Dispatch voiceDispatch = null;
Dispatch fileStreamDispatch = null;
Dispatch audioFormatDispatch = null;
try {
voiceComponent = new ActiveXComponent("Sapi.SpVoice");
fileStreamComponent = new ActiveXComponent("Sapi.SpFileStream");
audioComponent = new ActiveXComponent("Sapi.SpAudioFormat");
voiceDispatch = voiceComponent.getObject();
fileStreamDispatch = fileStreamComponent.getObject();
audioFormatDispatch = audioComponent.getObject();
Dispatch.put(audioFormatDispatch, "Type", new Variant(22));
Dispatch.putRef(fileStreamDispatch, "Format", audioFormatDispatch);
Dispatch.call(fileStreamDispatch, "Open", new Variant(output), new Variant(3), new Variant(true));
Dispatch.putRef(voiceDispatch, "AudioOutputStream", fileStreamDispatch);
voiceComponent.setProperty("Volume", new Variant(100));
voiceComponent.setProperty("Rate", new Variant(speed));
Dispatch.call(voiceDispatch, "Speak", new Variant(text));
Dispatch.call(fileStreamDispatch, "Close");
Dispatch.putRef(voiceDispatch, "AudioOutputStream", null);
} catch (Exception e) {
log.error("朗读文本异常", e);
throw e;
} finally {
if (voiceComponent != null) {
voiceComponent.safeRelease();
}
if (fileStreamComponent != null) {
fileStreamComponent.safeRelease();
}
if (audioComponent != null) {
audioComponent.safeRelease();
}
if (voiceDispatch != null) {
voiceDispatch.safeRelease();
}
if (fileStreamDispatch != null) {
fileStreamDispatch.safeRelease();
}
if (audioFormatDispatch != null) {
audioFormatDispatch.safeRelease();
}
}
}
}
4.接口
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.cloudbeing.api.util.VoiceUtil;
import com.cloudbeing.framework.common.controller.BaseController;
import com.cloudbeing.framework.web.util.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
/**
* 语音播放模块
*
* @author dev
*/
@Slf4j
@RestController
@RequestMapping("/test/voice")
public class PortalVoiceController {
private String voiceOutput = "D:\\data0\\voice\\";
@GetMapping("/speak")
public void speak(String text, Integer speed) throws IOException {
if (StrUtil.isEmpty(text)) {
return;
}
HttpServletResponse response = Response.getResponse();
response.setContentType("audio/wav");
Integer s = speed != null ? speed : -2;
String output = voiceOutput + MD5.create().digestHex(text) + s + ".wav";
if (!FileUtil.exist(output)) {
VoiceUtil.speak(text, s, output);
}
BufferedInputStream in = null;
try {
in = FileUtil.getInputStream(output);
IoUtil.copy(in, response.getOutputStream());
} finally {
IoUtil.close(in);
}
}
}
5.测试
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~