Java Nashorn引擎中SpeechSynthesis未定义问题及替代方案咨询
解决方案:Nashorn引擎实现语音合成及替代引擎推荐
一、为Nashorn创建模拟SpeechSynthesis接口
Nashorn是Java内置的服务器端JavaScript引擎,本身不支持浏览器的SpeechSynthesis Web API,但你可以通过Java语音合成库封装出兼容的接口,暴露给Nashorn使用。以下是具体实现步骤:
1. 选择Java语音合成库
常用的Java语音合成方案有两种:
- JavaFX SpeechSynthesizer:JDK 8及部分后续版本内置,适合桌面应用场景;
- FreeTTS:开源轻量库,无需依赖JavaFX,兼容性更广。
2. 封装Java类模拟SpeechSynthesis接口
以FreeTTS为例,先添加Maven依赖:
<dependency> <groupId>net.sf.sociaal</groupId> <artifactId>freetts</artifactId> <version>1.2.2</version> </dependency>
编写Java封装类,模拟浏览器的SpeechSynthesis和SpeechSynthesisUtterance结构:
import com.sun.speech.freetts.Voice; import com.sun.speech.freetts.VoiceManager; public class NashornSpeech { private final Voice voice; public NashornSpeech() { VoiceManager voiceManager = VoiceManager.getInstance(); // 选择FreeTTS自带的英文语音包 this.voice = voiceManager.getVoice("kevin16"); if (voice != null) { voice.allocate(); } } // 模拟speak方法 public void speak(SpeechUtterance utterance) { if (voice != null) { voice.speak(utterance.getText()); } } // 模拟SpeechSynthesisUtterance类 public static class SpeechUtterance { private String text; public SpeechUtterance(String text) { this.text = text; } public String getText() { return text; } } }
3. 在Nashorn中调用封装的接口
方式1:Java代码中集成Nashorn
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class NashornSpeechDemo { public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine nashorn = manager.getEngineByName("nashorn"); // 将Java语音对象暴露为全局变量speechSynthesis NashornSpeech speechSynthesis = new NashornSpeech(); nashorn.put("speechSynthesis", speechSynthesis); // 将Utterance类暴露给JavaScript nashorn.put("SpeechSynthesisUtterance", NashornSpeech.SpeechUtterance.class); // 执行目标JavaScript代码 nashorn.eval("speechSynthesis.speak(new SpeechSynthesisUtterance('Hello world!'));"); } }
方式2:直接在jjs工具中调用
编译上述Java类后,在jjs中加载并使用:
// 加载Java类 var NashornSpeech = Java.type("com.yourpackage.NashornSpeech"); var SpeechSynthesisUtterance = Java.type("com.yourpackage.NashornSpeech$SpeechUtterance"); // 创建全局语音对象 var speechSynthesis = new NashornSpeech(); // 调用语音合成 speechSynthesis.speak(new SpeechSynthesisUtterance("Hello world!"));
二、支持SpeechSynthesis的其他JavaScript引擎
如果不想手动封装,可选择自带浏览器环境或支持Web API的引擎:
- GraalVM + Node.js + 浏览器模拟库:GraalVM可运行Node.js,搭配
jsdom或playwright模拟浏览器环境,直接调用SpeechSynthesis API; - Electron渲染进程:Electron基于Chromium,其渲染进程完全支持浏览器Web API,包括SpeechSynthesis,适合开发桌面应用;
- 浏览器内置引擎:直接在Chrome、Firefox等浏览器的开发者工具中运行代码,原生支持SpeechSynthesis,但无法与Java直接集成;
- Rhino引擎:与Nashorn类似,默认不支持,但可通过相同的Java封装方式实现语音合成功能。
内容的提问来源于stack exchange,提问作者Annamalai Palanikumar
相关产品推荐
相关产品推荐

