Skip to content

Commit 69c1a49

Browse files
committed
feat: added initial impl of tts service
1 parent f754702 commit 69c1a49

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

fxgl-intelligence/src/main/java/com/almasb/fxgl/intelligence/WebAPI.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
*/
1515
public final class WebAPI {
1616

17+
public static final String TEXT_TO_SPEECH_API = "https://almasb.github.io/web-api/text-to-speech-v1/";
1718
public static final String SPEECH_RECOGNITION_API = "https://almasb.github.io/web-api/speech-recog/";
1819
public static final String GESTURE_RECOGNITION_API = "https://almasb.github.io/web-api/gesture-recog-v1/";
1920

21+
public static final int TEXT_TO_SPEECH_PORT = 55550;
2022
public static final int SPEECH_RECOGNITION_PORT = 55555;
2123
public static final int GESTURE_RECOGNITION_PORT = 55560;
2224
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* FXGL - JavaFX Game Library. The MIT License (MIT).
3+
* Copyright (c) AlmasB (almaslvl@gmail.com).
4+
* See LICENSE for details.
5+
*/
6+
7+
package com.almasb.fxgl.intelligence.tts
8+
9+
import com.almasb.fxgl.core.EngineService
10+
import com.almasb.fxgl.core.concurrent.Async
11+
import com.almasb.fxgl.intelligence.WebAPI
12+
import com.almasb.fxgl.logging.Logger
13+
import com.almasb.fxgl.net.ws.LocalWebSocketServer
14+
import com.almasb.fxgl.speechrecog.SpeechRecognitionService
15+
import org.openqa.selenium.By
16+
import org.openqa.selenium.WebDriver
17+
import org.openqa.selenium.chrome.ChromeDriver
18+
import org.openqa.selenium.chrome.ChromeOptions
19+
20+
/**
21+
* TODO: remove duplicate code
22+
*
23+
* @author Almas Baim (https://github.com/AlmasB)
24+
*/
25+
class TextToSpeechService : EngineService() {
26+
27+
private val log = Logger.get(TextToSpeechService::class.java)
28+
private val server = LocalWebSocketServer("TTSServer", WebAPI.TEXT_TO_SPEECH_PORT)
29+
30+
private var webDriver: WebDriver? = null
31+
32+
override fun onInit() {
33+
server.start()
34+
}
35+
36+
/**
37+
* Starts this service in a background thread.
38+
* Can be called after stop() to restart the service.
39+
* If the service has already started, then calls stop() and restarts it.
40+
*/
41+
fun start() {
42+
Async.startAsync {
43+
try {
44+
if (webDriver != null) {
45+
stop()
46+
}
47+
48+
val options = ChromeOptions()
49+
options.addArguments("--headless=new")
50+
options.addArguments("--use-fake-ui-for-media-stream")
51+
52+
webDriver = ChromeDriver(options)
53+
webDriver!!.get(WebAPI.TEXT_TO_SPEECH_API)
54+
55+
// TODO: update web-api impl
56+
// force it to play, so the audio output is initialized
57+
webDriver!!.findElement(By.id("play")).click()
58+
59+
// we are ready to use the web api service
60+
} catch (e: Exception) {
61+
log.warning("Failed to start Chrome web driver. Ensure Chrome is installed in default location")
62+
log.warning("Error data", e)
63+
}
64+
}
65+
}
66+
67+
/**
68+
* Stops this service.
69+
* No-op if it has not started via start() before.
70+
*/
71+
fun stop() {
72+
try {
73+
if (webDriver != null) {
74+
webDriver!!.quit()
75+
webDriver = null
76+
}
77+
} catch (e: Exception) {
78+
log.warning("Failed to quit web driver", e)
79+
}
80+
}
81+
82+
fun speak(text: String) {
83+
server.send(text)
84+
}
85+
86+
override fun onExit() {
87+
stop()
88+
server.stop()
89+
}
90+
}

0 commit comments

Comments
 (0)