commit 12/10/2025
This commit is contained in:
@@ -592,6 +592,17 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
})
|
||||
$('#ttsgenerator').click(() => {
|
||||
sidemenu.hide();
|
||||
$('#content').load('tts.html', function (response, status, xhr) {
|
||||
if (status === "success") {
|
||||
console.log("TTS Generator content loaded successfully");
|
||||
// pindah ke ttsgenerator.js
|
||||
} else {
|
||||
console.error("Error loading TTS Generator content:", xhr.status, xhr.statusText);
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#filemanagement').click(() => {
|
||||
sidemenu.hide();
|
||||
$('#content').load('filemanagement.html', function (response, status, xhr) {
|
||||
|
||||
78
html/webpage/assets/js/tts.js
Normal file
78
html/webpage/assets/js/tts.js
Normal file
@@ -0,0 +1,78 @@
|
||||
function websocket_init() {
|
||||
window.addEventListener('ws_connected', () => {
|
||||
console.log("tts.js ws_connected event triggered");
|
||||
});
|
||||
|
||||
window.addEventListener('ws_disconnected', () => {
|
||||
console.log("tts.js ws_disconnected event triggered");
|
||||
|
||||
});
|
||||
window.addEventListener('ws_message', (event) => {
|
||||
let rep = event.detail;
|
||||
let cmd = rep.reply;
|
||||
let data = rep.data;
|
||||
if (cmd && cmd.length > 0) {
|
||||
switch (cmd) {
|
||||
case "start_generate_tts":
|
||||
if (data && data.length>0 && "ok"===data){
|
||||
add_to_list("TTS generation started.");
|
||||
$('#startstopgeneration').text("Stop Generating");
|
||||
}
|
||||
break;
|
||||
case "stop_generate_tts":
|
||||
if (data && data.length>0 && "ok"===data){
|
||||
add_to_list("TTS generation stopped.");
|
||||
$('#startstopgeneration').text("Start Generating");
|
||||
}
|
||||
break;
|
||||
case "tts_generate_progress":
|
||||
if (data && data.length>0){
|
||||
let xx = JSON.parse(data);
|
||||
if ("progress" in xx){
|
||||
if ("message" in xx){
|
||||
add_to_list(xx.message + "(" + xx.progress+" %)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add_to_list(message){
|
||||
// add message to generatelogs list, with date time prefix
|
||||
let li = document.createElement("li");
|
||||
let now = new Date();
|
||||
let datetime = now.toLocaleString();
|
||||
li.appendChild(document.createTextNode("[" + datetime + "] " + message));
|
||||
$('#generatelogs').append(li);
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
console.log("TTS module loaded.");
|
||||
websocket_init();
|
||||
|
||||
$('#uploadjson').on('click', function () {
|
||||
// TODO upload JSON file and process it
|
||||
});
|
||||
$('#startstopgeneration').on('click', function () {
|
||||
if ($('#startstopgeneration').text() === "Start Generating") {
|
||||
// clear list generatelogs
|
||||
$('#generatelogs').empty();
|
||||
let data = {
|
||||
voicetype: $('#voicetype').val(),
|
||||
languagetogenerate: $('#languagetogenerate').val(),
|
||||
databasesource: $('#databasesource').val(),
|
||||
targetas: $('#targetas').val(),
|
||||
fileoperation: $('input[name="fileoperation"]:checked').val(),
|
||||
autoadd: $('input[name="autoadd"]:checked').val()
|
||||
}
|
||||
sendCommand("start_generate_tts", JSON.stringify(data));
|
||||
} else {
|
||||
sendCommand("stop_generate_tts", "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
@@ -88,6 +88,19 @@
|
||||
<path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"></path>
|
||||
</g>
|
||||
</svg> Setting</a></li>
|
||||
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="ttsgenerator" href="#"><svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu pad-icon-menu" style="font-size: 20px;">
|
||||
<g>
|
||||
<rect fill="none" height="24" width="24"></rect>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<circle cx="10" cy="9" r="4"></circle>
|
||||
<path d="M16.39,15.56C14.71,14.7,12.53,14,10,14c-2.53,0-4.71,0.7-6.39,1.56C2.61,16.07,2,17.1,2,18.22V21h16v-2.78 C18,17.1,17.39,16.07,16.39,15.56z"></path>
|
||||
<path d="M20.36,1l-1.41,1.41c2.73,2.73,2.73,7.17,0,9.9l1.41,1.41C23.88,10.21,23.88,4.51,20.36,1z"></path>
|
||||
<path d="M17.54,10.9c1.95-1.95,1.95-5.12,0-7.07l-1.41,1.41c1.17,1.17,1.17,3.07,0,4.24L17.54,10.9z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg> Text To Speech Generator</a></li>
|
||||
<li class="nav-item"><a class="nav-link link-body-emphasis text-menu" id="logoutlink" href="#"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor" class="me-2 icon-menu" style="font-size: 20px;">
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"></path>
|
||||
|
||||
129
html/webpage/tts.html
Normal file
129
html/webpage/tts.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html data-bs-theme="light" lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_28OKT25rev1</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Brands.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Duotone.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Pro.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Brands.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Duotone.css">
|
||||
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
|
||||
<link rel="stylesheet" href="assets/css/FontAwesome.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="row">
|
||||
<div class="col w-100 h-100 pad-header">
|
||||
<h2 style="text-align: center;">Text To Speech Content Generator</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card card-setting"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card card-setting">
|
||||
<div class="card-body pad-accordion">
|
||||
<h4 class="card-title">Google Parameter</h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-3 h-100"><label class="col-form-label">Application Credential JSON</label></div>
|
||||
<div class="col"><input class="w-100 h-100" type="file" id="jsonfilechooser"></div>
|
||||
<div class="col-2"><button class="btn btn-primary w-100 h-100" id="uploadjson" type="button">Upload</button></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3 h-100"><label class="col-form-label h-100">Voice Type</label></div>
|
||||
<div class="col"><select class="h-100" id="voicetype">
|
||||
<option value="Wavenet-A" selected="">Female 1</option>
|
||||
<option value="Wavenet-D">Female 2</option>
|
||||
<option value="Wavenet-B">Male 1</option>
|
||||
<option value="Wavenet-C">Male 2</option>
|
||||
<option value=""></option>
|
||||
</select></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card card-setting">
|
||||
<div class="card-body pad-accordion">
|
||||
<h4 class="card-title">Content Generator</h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-3"><label class="col-form-label h-100">Language to Generate</label></div>
|
||||
<div class="col-2"><select class="h-100" id="languagetogenerate">
|
||||
<option value="id-ID" selected="">Indonesia</option>
|
||||
<option value="en-us">English</option>
|
||||
<option value="ja-JP">Japanese</option>
|
||||
<option value="zh-CN">Chinese</option>
|
||||
<option value="ar-SA">Arabic</option>
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"><label class="col-form-label h-100">Database Source</label></div>
|
||||
<div class="col-2"><select class="h-100" id="databasesource">
|
||||
<option value="VOICE_1" selected="">Voice 1</option>
|
||||
<option value="VOICE_2">Voice 2</option>
|
||||
<option value="VOICE_3">Voice 3</option>
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"><label class="col-form-label h-100">Target As</label></div>
|
||||
<div class="col-2"><select class="w-100 h-100" id="targetas">
|
||||
<option value="VOICE_1">Voice 1</option>
|
||||
<option value="VOICE_2" selected="">Voice 2</option>
|
||||
<option value="VOICE_3">Voice 3</option>
|
||||
</select></div>
|
||||
<div class="col-3">
|
||||
<div class="row"><label class="form-label fw-semibold">File Operation</label></div>
|
||||
<div class="row">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="formCheck-1" name="fileoperation" value="skip" checked=""><label class="form-check-label" for="formCheck-1">Skip when exists</label></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="formCheck-2" name="fileoperation" value="overwrite"><label class="form-check-label" for="formCheck-2">Overwrite</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row"><label class="form-label fw-semibold">Database Operation</label></div>
|
||||
<div class="row">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="formCheck-3" name="autoadd" value="add" checked=""><label class="form-check-label" for="formCheck-3">Auto Add when not exists</label></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="formCheck-4" name="autoadd" value="skip"><label class="form-check-label" for="formCheck-4">Skip</label></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row"><button class="btn btn-primary" id="startstopgeneration" type="button">Start Generating</button></div>
|
||||
<div class="row">
|
||||
<div class="progress w-100 invisible" id="generateprogress">
|
||||
<div class="progress-bar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">0%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<ul class="list-unstyled w-100 h-100" id="generatelogs"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="assets/js/bs-init.js"></script>
|
||||
<script src="assets/js/tts.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -181,6 +181,10 @@ class Somecodes {
|
||||
} else cb.accept(-1,-1)
|
||||
}
|
||||
|
||||
fun GetFilename(path: String) : String {
|
||||
return Path.of(path).fileName.toString()
|
||||
}
|
||||
|
||||
fun ExtractFilesFromClassPath(resourcePath: String, outputDir: Path) {
|
||||
try {
|
||||
val resource = Somecodes::class.java.getResource(resourcePath)
|
||||
|
||||
@@ -1,21 +1,126 @@
|
||||
package google
|
||||
|
||||
import codes.Somecodes
|
||||
import com.google.cloud.texttospeech.v1.AudioConfig
|
||||
import com.google.cloud.texttospeech.v1.AudioEncoding
|
||||
import com.google.cloud.texttospeech.v1.SynthesisInput
|
||||
import com.google.cloud.texttospeech.v1.TextToSpeechClient
|
||||
import com.google.cloud.texttospeech.v1.VoiceSelectionParams
|
||||
import content.Category
|
||||
import content.Language
|
||||
import content.VoiceType
|
||||
import database.Soundbank
|
||||
import org.tinylog.Logger
|
||||
import java.nio.file.Files
|
||||
import java.util.function.BiConsumer
|
||||
import kotlin.io.path.Path
|
||||
import db
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.absolutePathString
|
||||
|
||||
@Suppress("unused")
|
||||
class GoogleTTS(credentialJson: String = "c:/googlettsapi/gtc-cloud-aas-ae23c9552e1f.json") {
|
||||
private var isGeneratingSoundbank = false
|
||||
init{
|
||||
System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", credentialJson)
|
||||
}
|
||||
|
||||
fun Speak(text: String, language : GoogleTTSLanguage, voicetype: GoogleTTSVoiceType, targetfilename: String){
|
||||
/**
|
||||
* Generate soundbank
|
||||
* @param voicetype Voice type, default Wavenet-A
|
||||
* @param language Language of the soundbank, default INDONESIA
|
||||
* @param databasesource Database source, default VOICE_1
|
||||
* @param targetas Target as, default VOICE_2
|
||||
* @param file_operation File operation, options are overwrite or skip, default overwrite
|
||||
* @param auto_add Auto add, options are add or skip, default add
|
||||
*/
|
||||
fun GenerateSoundbank(voicetype: String = "Wavenet-A", language: Language = Language.INDONESIA, databasesource: VoiceType = VoiceType.VOICE_1, targetas: VoiceType = VoiceType.VOICE_2, file_operation: fileoperation , auto_add: autoadd, progress: BiConsumer<Int, String>){
|
||||
val source = db.soundDB.List
|
||||
.filter { it.VoiceType==databasesource.name}
|
||||
.filter { it.Language==language.name }
|
||||
val target = db.soundDB.List
|
||||
.filter { it.VoiceType==targetas.name}
|
||||
.filter { it.Language==language.name }
|
||||
if (source.isNotEmpty()){
|
||||
isGeneratingSoundbank = true
|
||||
source.forEachIndexed { index, s ->
|
||||
if (!isGeneratingSoundbank){
|
||||
Logger.info { "Soundbank generation stopped by user" }
|
||||
progress.accept(index, "Stopped by user")
|
||||
return@forEachIndexed
|
||||
}
|
||||
|
||||
val targetfolder = Somecodes.SoundbankDirectory(language, targetas, Category.valueOf(s.Category))
|
||||
val targetfile = Somecodes.GetFilename(s.Path)
|
||||
val fullpath = targetfolder.resolve(targetfile)
|
||||
|
||||
var targetrow = target.find { it.Category == s.Category && it.TAG == s.TAG }
|
||||
|
||||
if (Files.exists(fullpath) && file_operation == fileoperation.SKIP){
|
||||
// file exists, skip, not creating new file
|
||||
Logger.info { "Skipping existing file : ${fullpath.absolutePathString()}" }
|
||||
progress.accept(index , "Skipping existing file : ${fullpath.absolutePathString()}")
|
||||
if (targetrow==null && auto_add == autoadd.ADD){
|
||||
// file ada, tapi tidak ada di database target, add ke database
|
||||
// add ke target database
|
||||
targetrow = Soundbank(
|
||||
index =0U,
|
||||
Description = s.Description,
|
||||
TAG = s.TAG,
|
||||
Category = s.Category,
|
||||
Language = s.Language,
|
||||
VoiceType = targetas.name,
|
||||
Path = fullpath.absolutePathString()
|
||||
)
|
||||
db.soundDB.Add(targetrow)
|
||||
Logger.info { "Added to target database TAG ${s.TAG} Category ${s.Category}" }
|
||||
progress.accept(index , "Added to target database TAG ${s.TAG} Category ${s.Category}")
|
||||
}
|
||||
|
||||
} else {
|
||||
// file not exists, or overwrite
|
||||
if (targetrow!=null){
|
||||
// ada
|
||||
Speak(
|
||||
text = s.Description,
|
||||
language = GoogleTTSLanguage.fromLanguage(Language.valueOf(s.Language)),
|
||||
voicetype = GoogleTTSVoiceType.valueOf(voicetype),
|
||||
targetfilename = fullpath.absolutePathString()
|
||||
){
|
||||
success, message ->
|
||||
if (success){
|
||||
|
||||
} else {
|
||||
Logger.error { "Failed to generate sound for TAG ${s.TAG} Category ${s.Category}, message : $message" }
|
||||
progress.accept(index , "Failed to generate sound for TAG ${s.TAG} Category ${s.Category}, message : $message")
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// tidak ada
|
||||
if (auto_add == autoadd.ADD){
|
||||
// add ke target database
|
||||
} else {
|
||||
// skip
|
||||
Logger.info { "Skipping TAG ${s.TAG} Category ${s.Category} as it does not exist in target database" }
|
||||
progress.accept(index , "Skipping TAG ${s.TAG} Category ${s.Category} as it does not exist in target database")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
isGeneratingSoundbank = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop generate soundbank
|
||||
*/
|
||||
fun StopGenerate(){
|
||||
isGeneratingSoundbank = false
|
||||
}
|
||||
|
||||
fun Speak(text: String, language : GoogleTTSLanguage, voicetype: GoogleTTSVoiceType, targetfilename: String, event: BiConsumer<Boolean, String>? = null){
|
||||
TextToSpeechClient.create().use { client ->
|
||||
try{
|
||||
val input = SynthesisInput.newBuilder().setText(text).build()
|
||||
@@ -32,12 +137,12 @@ class GoogleTTS(credentialJson: String = "c:/googlettsapi/gtc-cloud-aas-ae23c955
|
||||
val target = Path(targetfilename)
|
||||
Files.write(target, bytes)
|
||||
Logger.info { "Speak success, file saved to : $targetfilename" }
|
||||
event?.accept(true, targetfilename)
|
||||
} catch (e : Exception){
|
||||
Logger.error { "Speak failed, message : ${e.message}" }
|
||||
event?.accept(false, e.message ?: "Unknown error")
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,27 @@
|
||||
package google
|
||||
|
||||
import content.Language
|
||||
|
||||
@Suppress("unused")
|
||||
enum class GoogleTTSLanguage(code: String) {
|
||||
Indonesia("id-ID"),
|
||||
English("en-US"),
|
||||
Japanese("ja-JP"),
|
||||
Chinese("zh-CN"),
|
||||
Arabic("ar-SA")
|
||||
Arabic("ar-SA");
|
||||
|
||||
companion object {
|
||||
fun fromLanguage(lang: Language) : GoogleTTSLanguage {
|
||||
return when(lang) {
|
||||
Language.INDONESIA -> Indonesia
|
||||
Language.ENGLISH -> English
|
||||
Language.JAPANESE -> Japanese
|
||||
Language.CHINESE -> Chinese
|
||||
Language.ARABIC -> Arabic
|
||||
else -> Indonesia
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
7
src/google/autoadd.kt
Normal file
7
src/google/autoadd.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package google
|
||||
|
||||
@Suppress("unused")
|
||||
enum class autoadd(name: String) {
|
||||
ADD("add"),
|
||||
SKIP("skip");
|
||||
}
|
||||
7
src/google/fileoperation.kt
Normal file
7
src/google/fileoperation.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package google
|
||||
|
||||
@Suppress("unused")
|
||||
enum class fileoperation(name: String) {
|
||||
OVERWRITE("overwrite"),
|
||||
SKIP("skip");
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import java.time.LocalDateTime
|
||||
import codes.configKeys
|
||||
import config
|
||||
import database.QueueTable
|
||||
import google.GoogleTTS
|
||||
import io.javalin.websocket.WsCloseStatus
|
||||
import org.tinylog.Logger
|
||||
import java.io.File
|
||||
@@ -59,6 +60,7 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
||||
lateinit var semiauto: Javalin
|
||||
val objectmapper = jacksonObjectMapper()
|
||||
val WsContextMap = mutableMapOf<String, LiveListenData>()
|
||||
val ttsjob = GoogleTTS()
|
||||
|
||||
private fun SendReply(context: WsMessageContext, command: String, value: String) {
|
||||
try {
|
||||
@@ -201,6 +203,32 @@ class WebApp(val listenPort: Int, var userlist: List<Pair<String, String>>, val
|
||||
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(reply))
|
||||
}
|
||||
|
||||
"start_generate_tts" ->{
|
||||
val js : JsonNode = objectmapper.readTree(cmd.data)
|
||||
SendReply(wsMessageContext, cmd.command, "ok")
|
||||
val voicetype = js.get("voicetype")?.asText("Wavenet-A") ?: "Wavenet-A"
|
||||
val languagecode = js.get("languagecode")?.asText("id-ID") ?: "id-ID"
|
||||
val databasesource = js.get("databasesource")?.asText("VOICE_1") ?: "VOICE_1"
|
||||
val targetas = js.get("targetas")?.asText("VOICE_2") ?: "VOICE_2"
|
||||
val fileoperation = js.get("fileoperation")?.asText("overwrite") ?: "overwrite"
|
||||
val autoadd = js.get("autoadd")?.asText("add") ?: "add"
|
||||
Logger.info {"Starting TTS Soundbank Generation, VoiceType=$voicetype, Language"}
|
||||
ttsjob.GenerateSoundbank(voicetype, languagecode, databasesource, targetas, fileoperation, autoadd){ progress, message ->
|
||||
SendReply(wsMessageContext, "tts_generate_progress", objectmapper.writeValueAsString(
|
||||
mapOf(
|
||||
"progress" to progress,
|
||||
"message" to message
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
"stop_generate_tts" ->{
|
||||
SendReply(wsMessageContext, cmd.command, "ok")
|
||||
ttsjob.StopGenerate()
|
||||
|
||||
}
|
||||
|
||||
else -> {
|
||||
SendReply(wsMessageContext, cmd.command, "Unknown command")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user