mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Require single quotes
This commit is contained in:
@ -4,13 +4,13 @@ TODO:
|
||||
- Delete useless call
|
||||
*/
|
||||
|
||||
import { doExtrasFetch, extension_settings, getApiUrl, modules } from "../../extensions.js"
|
||||
import { callPopup } from "../../../script.js"
|
||||
import { initVoiceMap } from "./index.js"
|
||||
import { doExtrasFetch, extension_settings, getApiUrl, modules } from '../../extensions.js'
|
||||
import { callPopup } from '../../../script.js'
|
||||
import { initVoiceMap } from './index.js'
|
||||
|
||||
export { CoquiTtsProvider }
|
||||
|
||||
const DEBUG_PREFIX = "<Coqui TTS module> ";
|
||||
const DEBUG_PREFIX = '<Coqui TTS module> ';
|
||||
|
||||
let inApiCall = false;
|
||||
let coquiApiModels = {}; // Initialized only once
|
||||
@ -33,24 +33,24 @@ coquiApiModels format [language][dataset][name]:coqui-api-model-id, example:
|
||||
}
|
||||
*/
|
||||
const languageLabels = {
|
||||
"multilingual": "Multilingual",
|
||||
"en": "English",
|
||||
"fr": "French",
|
||||
"es": "Spanish",
|
||||
"ja": "Japanese"
|
||||
'multilingual': 'Multilingual',
|
||||
'en': 'English',
|
||||
'fr': 'French',
|
||||
'es': 'Spanish',
|
||||
'ja': 'Japanese'
|
||||
}
|
||||
|
||||
function throwIfModuleMissing() {
|
||||
if (!modules.includes('coqui-tts')) {
|
||||
const message = `Coqui TTS module not loaded. Add coqui-tts to enable-modules and restart the Extras API.`
|
||||
const message = 'Coqui TTS module not loaded. Add coqui-tts to enable-modules and restart the Extras API.'
|
||||
// toastr.error(message, { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
throw new Error(DEBUG_PREFIX, message);
|
||||
}
|
||||
}
|
||||
|
||||
function resetModelSettings() {
|
||||
$("#coqui_api_model_settings_language").val("none");
|
||||
$("#coqui_api_model_settings_speaker").val("none");
|
||||
$('#coqui_api_model_settings_language').val('none');
|
||||
$('#coqui_api_model_settings_speaker').val('none');
|
||||
}
|
||||
|
||||
class CoquiTtsProvider {
|
||||
@ -138,29 +138,29 @@ class CoquiTtsProvider {
|
||||
await initLocalModels();
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
|
||||
$("#coqui_api_model_div").hide();
|
||||
$("#coqui_local_model_div").hide();
|
||||
$('#coqui_api_model_div').hide();
|
||||
$('#coqui_local_model_div').hide();
|
||||
|
||||
$("#coqui_api_language").show();
|
||||
$("#coqui_api_model_name").hide();
|
||||
$("#coqui_api_model_settings").hide();
|
||||
$("#coqui_api_model_install_status").hide();
|
||||
$("#coqui_api_model_install_button").hide();
|
||||
$('#coqui_api_language').show();
|
||||
$('#coqui_api_model_name').hide();
|
||||
$('#coqui_api_model_settings').hide();
|
||||
$('#coqui_api_model_install_status').hide();
|
||||
$('#coqui_api_model_install_button').hide();
|
||||
|
||||
let that = this
|
||||
$("#coqui_model_origin").on("change", function () { that.onModelOriginChange() });
|
||||
$("#coqui_api_language").on("change", function () { that.onModelLanguageChange() });
|
||||
$("#coqui_api_model_name").on("change", function () { that.onModelNameChange() });
|
||||
$('#coqui_model_origin').on('change', function () { that.onModelOriginChange() });
|
||||
$('#coqui_api_language').on('change', function () { that.onModelLanguageChange() });
|
||||
$('#coqui_api_model_name').on('change', function () { that.onModelNameChange() });
|
||||
|
||||
$("#coqui_remove_voiceId_mapping").on("click", function () { that.onRemoveClick() });
|
||||
$("#coqui_add_voiceId_mapping").on("click", function () { that.onAddClick() });
|
||||
$('#coqui_remove_voiceId_mapping').on('click', function () { that.onRemoveClick() });
|
||||
$('#coqui_add_voiceId_mapping').on('click', function () { that.onAddClick() });
|
||||
|
||||
// Load coqui-api settings from json file
|
||||
await fetch("/scripts/extensions/tts/coqui_api_models_settings.json")
|
||||
await fetch('/scripts/extensions/tts/coqui_api_models_settings.json')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
coquiApiModels = json;
|
||||
console.debug(DEBUG_PREFIX,"initialized coqui-api model list to", coquiApiModels);
|
||||
console.debug(DEBUG_PREFIX,'initialized coqui-api model list to', coquiApiModels);
|
||||
/*
|
||||
$('#coqui_api_language')
|
||||
.find('option')
|
||||
@ -176,11 +176,11 @@ class CoquiTtsProvider {
|
||||
});
|
||||
|
||||
// Load coqui-api FULL settings from json file
|
||||
await fetch("/scripts/extensions/tts/coqui_api_models_settings_full.json")
|
||||
await fetch('/scripts/extensions/tts/coqui_api_models_settings_full.json')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
coquiApiModelsFull = json;
|
||||
console.debug(DEBUG_PREFIX,"initialized coqui-api full model list to", coquiApiModelsFull);
|
||||
console.debug(DEBUG_PREFIX,'initialized coqui-api full model list to', coquiApiModelsFull);
|
||||
/*
|
||||
$('#coqui_api_full_language')
|
||||
.find('option')
|
||||
@ -207,17 +207,17 @@ class CoquiTtsProvider {
|
||||
this.settings.customVoices = {};
|
||||
for (let voiceName in this.settings.voiceMapDict) {
|
||||
const voiceId = this.settings.voiceMapDict[voiceName];
|
||||
this.settings.customVoices[voiceName] = voiceId["model_id"];
|
||||
this.settings.customVoices[voiceName] = voiceId['model_id'];
|
||||
|
||||
if (voiceId["model_language"] != null)
|
||||
this.settings.customVoices[voiceName] += "[" + voiceId["model_language"] + "]";
|
||||
if (voiceId['model_language'] != null)
|
||||
this.settings.customVoices[voiceName] += '[' + voiceId['model_language'] + ']';
|
||||
|
||||
if (voiceId["model_speaker"] != null)
|
||||
this.settings.customVoices[voiceName] += "[" + voiceId["model_speaker"] + "]";
|
||||
if (voiceId['model_speaker'] != null)
|
||||
this.settings.customVoices[voiceName] += '[' + voiceId['model_speaker'] + ']';
|
||||
}
|
||||
|
||||
// Update UI select list with voices
|
||||
$("#coqui_voicename_select").empty()
|
||||
$('#coqui_voicename_select').empty()
|
||||
$('#coqui_voicename_select')
|
||||
.find('option')
|
||||
.remove()
|
||||
@ -225,14 +225,14 @@ class CoquiTtsProvider {
|
||||
.append('<option value="none">Select Voice</option>')
|
||||
.val('none')
|
||||
for (const voiceName in this.settings.voiceMapDict) {
|
||||
$("#coqui_voicename_select").append(new Option(voiceName, voiceName));
|
||||
$('#coqui_voicename_select').append(new Option(voiceName, voiceName));
|
||||
}
|
||||
|
||||
this.onSettingsChange()
|
||||
}
|
||||
|
||||
onSettingsChange() {
|
||||
console.debug(DEBUG_PREFIX, "Settings changes", this.settings);
|
||||
console.debug(DEBUG_PREFIX, 'Settings changes', this.settings);
|
||||
extension_settings.tts.Coqui = this.settings;
|
||||
}
|
||||
|
||||
@ -248,92 +248,92 @@ class CoquiTtsProvider {
|
||||
// Ask user for voiceId name to save voice
|
||||
const voiceName = await callPopup('<h3>Name of Coqui voice to add to voice select dropdown:</h3>', 'input')
|
||||
|
||||
const model_origin = $("#coqui_model_origin").val();
|
||||
const model_language = $("#coqui_api_language").val();
|
||||
const model_name = $("#coqui_api_model_name").val();
|
||||
let model_setting_language = $("#coqui_api_model_settings_language").val();
|
||||
let model_setting_speaker = $("#coqui_api_model_settings_speaker").val();
|
||||
const model_origin = $('#coqui_model_origin').val();
|
||||
const model_language = $('#coqui_api_language').val();
|
||||
const model_name = $('#coqui_api_model_name').val();
|
||||
let model_setting_language = $('#coqui_api_model_settings_language').val();
|
||||
let model_setting_speaker = $('#coqui_api_model_settings_speaker').val();
|
||||
|
||||
|
||||
if (!voiceName) {
|
||||
toastr.error(`Voice name empty, please enter one.`, DEBUG_PREFIX + " voice mapping voice name", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
toastr.error('Voice name empty, please enter one.', DEBUG_PREFIX + ' voice mapping voice name', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_origin == "none") {
|
||||
toastr.error(`Origin not selected, please select one.`, DEBUG_PREFIX + " voice mapping origin", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_origin == 'none') {
|
||||
toastr.error('Origin not selected, please select one.', DEBUG_PREFIX + ' voice mapping origin', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_origin == "local") {
|
||||
const model_id = $("#coqui_local_model_name").val();
|
||||
if (model_origin == 'local') {
|
||||
const model_id = $('#coqui_local_model_name').val();
|
||||
|
||||
if (model_name == "none") {
|
||||
toastr.error(`Model not selected, please select one.`, DEBUG_PREFIX + " voice mapping model", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_name == 'none') {
|
||||
toastr.error('Model not selected, please select one.', DEBUG_PREFIX + ' voice mapping model', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.voiceMapDict[voiceName] = { model_type: "local", model_id: "local/" + model_id };
|
||||
console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceName, ":", this.settings.voiceMapDict[voiceName]);
|
||||
this.settings.voiceMapDict[voiceName] = { model_type: 'local', model_id: 'local/' + model_id };
|
||||
console.debug(DEBUG_PREFIX, 'Registered new voice map: ', voiceName, ':', this.settings.voiceMapDict[voiceName]);
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_language == "none") {
|
||||
toastr.error(`Language not selected, please select one.`, DEBUG_PREFIX + " voice mapping language", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_language == 'none') {
|
||||
toastr.error('Language not selected, please select one.', DEBUG_PREFIX + ' voice mapping language', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_name == "none") {
|
||||
toastr.error(`Model not selected, please select one.`, DEBUG_PREFIX + " voice mapping model", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_name == 'none') {
|
||||
toastr.error('Model not selected, please select one.', DEBUG_PREFIX + ' voice mapping model', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
this.updateCustomVoices(); // Overide any manual modification
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_setting_language == "none")
|
||||
if (model_setting_language == 'none')
|
||||
model_setting_language = null;
|
||||
|
||||
if (model_setting_speaker == "none")
|
||||
if (model_setting_speaker == 'none')
|
||||
model_setting_speaker = null;
|
||||
|
||||
const tokens = $('#coqui_api_model_name').val().split("/");
|
||||
const tokens = $('#coqui_api_model_name').val().split('/');
|
||||
const model_dataset = tokens[0];
|
||||
const model_label = tokens[1];
|
||||
const model_id = "tts_models/" + model_language + "/" + model_dataset + "/" + model_label
|
||||
const model_id = 'tts_models/' + model_language + '/' + model_dataset + '/' + model_label
|
||||
|
||||
let modelDict = coquiApiModels
|
||||
if (model_origin == "coqui-api-full")
|
||||
if (model_origin == 'coqui-api-full')
|
||||
modelDict = coquiApiModelsFull
|
||||
|
||||
if (model_setting_language == null & "languages" in modelDict[model_language][model_dataset][model_label]) {
|
||||
toastr.error(`Model language not selected, please select one.`, DEBUG_PREFIX+" voice mapping model language", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_setting_language == null & 'languages' in modelDict[model_language][model_dataset][model_label]) {
|
||||
toastr.error('Model language not selected, please select one.', DEBUG_PREFIX+' voice mapping model language', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_setting_speaker == null & "speakers" in modelDict[model_language][model_dataset][model_label]) {
|
||||
toastr.error(`Model speaker not selected, please select one.`, DEBUG_PREFIX+" voice mapping model speaker", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (model_setting_speaker == null & 'speakers' in modelDict[model_language][model_dataset][model_label]) {
|
||||
toastr.error('Model speaker not selected, please select one.', DEBUG_PREFIX+' voice mapping model speaker', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug(DEBUG_PREFIX, "Current custom voices: ", this.settings.customVoices);
|
||||
console.debug(DEBUG_PREFIX, 'Current custom voices: ', this.settings.customVoices);
|
||||
|
||||
this.settings.voiceMapDict[voiceName] = { model_type: "coqui-api", model_id: model_id, model_language: model_setting_language, model_speaker: model_setting_speaker };
|
||||
this.settings.voiceMapDict[voiceName] = { model_type: 'coqui-api', model_id: model_id, model_language: model_setting_language, model_speaker: model_setting_speaker };
|
||||
|
||||
console.debug(DEBUG_PREFIX, "Registered new voice map: ", voiceName, ":", this.settings.voiceMapDict[voiceName]);
|
||||
console.debug(DEBUG_PREFIX, 'Registered new voice map: ', voiceName, ':', this.settings.voiceMapDict[voiceName]);
|
||||
|
||||
this.updateCustomVoices();
|
||||
initVoiceMap() // Update TTS extension voiceMap
|
||||
|
||||
let successMsg = voiceName + ":" + model_id;
|
||||
let successMsg = voiceName + ':' + model_id;
|
||||
if (model_setting_language != null)
|
||||
successMsg += "[" + model_setting_language + "]";
|
||||
successMsg += '[' + model_setting_language + ']';
|
||||
if (model_setting_speaker != null)
|
||||
successMsg += "[" + model_setting_speaker + "]";
|
||||
toastr.info(successMsg, DEBUG_PREFIX + " voice map updated", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
successMsg += '[' + model_setting_speaker + ']';
|
||||
toastr.info(successMsg, DEBUG_PREFIX + ' voice map updated', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
|
||||
return
|
||||
}
|
||||
@ -350,10 +350,10 @@ class CoquiTtsProvider {
|
||||
}
|
||||
|
||||
async onRemoveClick() {
|
||||
const voiceName = $("#coqui_voicename_select").val();
|
||||
const voiceName = $('#coqui_voicename_select').val();
|
||||
|
||||
if (voiceName === "none") {
|
||||
toastr.error(`Voice not selected, please select one.`, DEBUG_PREFIX + " voice mapping voiceId", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
if (voiceName === 'none') {
|
||||
toastr.error('Voice not selected, please select one.', DEBUG_PREFIX + ' voice mapping voiceId', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -368,14 +368,14 @@ class CoquiTtsProvider {
|
||||
resetModelSettings();
|
||||
const model_origin = $('#coqui_model_origin').val();
|
||||
|
||||
if (model_origin == "none") {
|
||||
$("#coqui_local_model_div").hide();
|
||||
$("#coqui_api_model_div").hide();
|
||||
if (model_origin == 'none') {
|
||||
$('#coqui_local_model_div').hide();
|
||||
$('#coqui_api_model_div').hide();
|
||||
}
|
||||
|
||||
// show coqui model selected list (SAFE)
|
||||
if (model_origin == "coqui-api") {
|
||||
$("#coqui_local_model_div").hide();
|
||||
if (model_origin == 'coqui-api') {
|
||||
$('#coqui_local_model_div').hide();
|
||||
|
||||
$('#coqui_api_language')
|
||||
.find('option')
|
||||
@ -388,16 +388,16 @@ class CoquiTtsProvider {
|
||||
let languageLabel = language
|
||||
if (language in languageLabels)
|
||||
languageLabel = languageLabels[language]
|
||||
$("#coqui_api_language").append(new Option(languageLabel,language));
|
||||
console.log(DEBUG_PREFIX,"added language",languageLabel,"(",language,")");
|
||||
$('#coqui_api_language').append(new Option(languageLabel,language));
|
||||
console.log(DEBUG_PREFIX,'added language',languageLabel,'(',language,')');
|
||||
}
|
||||
|
||||
$("#coqui_api_model_div").show();
|
||||
$('#coqui_api_model_div').show();
|
||||
}
|
||||
|
||||
// show coqui model full list (UNSAFE)
|
||||
if (model_origin == "coqui-api-full") {
|
||||
$("#coqui_local_model_div").hide();
|
||||
if (model_origin == 'coqui-api-full') {
|
||||
$('#coqui_local_model_div').hide();
|
||||
|
||||
$('#coqui_api_language')
|
||||
.find('option')
|
||||
@ -410,35 +410,35 @@ class CoquiTtsProvider {
|
||||
let languageLabel = language
|
||||
if (language in languageLabels)
|
||||
languageLabel = languageLabels[language]
|
||||
$("#coqui_api_language").append(new Option(languageLabel,language));
|
||||
console.log(DEBUG_PREFIX,"added language",languageLabel,"(",language,")");
|
||||
$('#coqui_api_language').append(new Option(languageLabel,language));
|
||||
console.log(DEBUG_PREFIX,'added language',languageLabel,'(',language,')');
|
||||
}
|
||||
|
||||
$("#coqui_api_model_div").show();
|
||||
$('#coqui_api_model_div').show();
|
||||
}
|
||||
|
||||
|
||||
// show local model list
|
||||
if (model_origin == "local") {
|
||||
$("#coqui_api_model_div").hide();
|
||||
$("#coqui_local_model_div").show();
|
||||
if (model_origin == 'local') {
|
||||
$('#coqui_api_model_div').hide();
|
||||
$('#coqui_local_model_div').show();
|
||||
}
|
||||
}
|
||||
|
||||
async onModelLanguageChange() {
|
||||
throwIfModuleMissing();
|
||||
resetModelSettings();
|
||||
$("#coqui_api_model_settings").hide();
|
||||
$('#coqui_api_model_settings').hide();
|
||||
const model_origin = $('#coqui_model_origin').val();
|
||||
const model_language = $('#coqui_api_language').val();
|
||||
console.debug(model_language);
|
||||
|
||||
if (model_language == "none") {
|
||||
$("#coqui_api_model_name").hide();
|
||||
if (model_language == 'none') {
|
||||
$('#coqui_api_model_name').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$("#coqui_api_model_name").show();
|
||||
$('#coqui_api_model_name').show();
|
||||
$('#coqui_api_model_name')
|
||||
.find('option')
|
||||
.remove()
|
||||
@ -447,45 +447,45 @@ class CoquiTtsProvider {
|
||||
.val('none');
|
||||
|
||||
let modelDict = coquiApiModels
|
||||
if (model_origin == "coqui-api-full")
|
||||
if (model_origin == 'coqui-api-full')
|
||||
modelDict = coquiApiModelsFull
|
||||
|
||||
for(let model_dataset in modelDict[model_language])
|
||||
for(let model_name in modelDict[model_language][model_dataset]) {
|
||||
const model_id = model_dataset + "/" + model_name
|
||||
const model_label = model_name + " (" + model_dataset + " dataset)"
|
||||
$("#coqui_api_model_name").append(new Option(model_label, model_id));
|
||||
const model_id = model_dataset + '/' + model_name
|
||||
const model_label = model_name + ' (' + model_dataset + ' dataset)'
|
||||
$('#coqui_api_model_name').append(new Option(model_label, model_id));
|
||||
}
|
||||
}
|
||||
|
||||
async onModelNameChange() {
|
||||
throwIfModuleMissing();
|
||||
resetModelSettings();
|
||||
$("#coqui_api_model_settings").hide();
|
||||
$('#coqui_api_model_settings').hide();
|
||||
const model_origin = $('#coqui_model_origin').val();
|
||||
|
||||
// No model selected
|
||||
if ($('#coqui_api_model_name').val() == "none") {
|
||||
$("#coqui_api_model_install_button").off('click');
|
||||
$("#coqui_api_model_install_button").hide();
|
||||
if ($('#coqui_api_model_name').val() == 'none') {
|
||||
$('#coqui_api_model_install_button').off('click');
|
||||
$('#coqui_api_model_install_button').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get languages and speakers options
|
||||
const model_language = $('#coqui_api_language').val();
|
||||
const tokens = $('#coqui_api_model_name').val().split("/");
|
||||
const tokens = $('#coqui_api_model_name').val().split('/');
|
||||
const model_dataset = tokens[0];
|
||||
const model_name = tokens[1];
|
||||
|
||||
let modelDict = coquiApiModels
|
||||
if (model_origin == "coqui-api-full")
|
||||
if (model_origin == 'coqui-api-full')
|
||||
modelDict = coquiApiModelsFull
|
||||
|
||||
const model_settings = modelDict[model_language][model_dataset][model_name]
|
||||
|
||||
if ("languages" in model_settings) {
|
||||
$("#coqui_api_model_settings").show();
|
||||
$("#coqui_api_model_settings_language").show();
|
||||
if ('languages' in model_settings) {
|
||||
$('#coqui_api_model_settings').show();
|
||||
$('#coqui_api_model_settings_language').show();
|
||||
$('#coqui_api_model_settings_language')
|
||||
.find('option')
|
||||
.remove()
|
||||
@ -493,18 +493,18 @@ class CoquiTtsProvider {
|
||||
.append('<option value="none">Select language</option>')
|
||||
.val('none');
|
||||
|
||||
for (let i = 0; i < model_settings["languages"].length; i++) {
|
||||
const language_label = JSON.stringify(model_settings["languages"][i]).replaceAll("\"", "");
|
||||
$("#coqui_api_model_settings_language").append(new Option(language_label, i));
|
||||
for (let i = 0; i < model_settings['languages'].length; i++) {
|
||||
const language_label = JSON.stringify(model_settings['languages'][i]).replaceAll('"', '');
|
||||
$('#coqui_api_model_settings_language').append(new Option(language_label, i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$("#coqui_api_model_settings_language").hide();
|
||||
$('#coqui_api_model_settings_language').hide();
|
||||
}
|
||||
|
||||
if ("speakers" in model_settings) {
|
||||
$("#coqui_api_model_settings").show();
|
||||
$("#coqui_api_model_settings_speaker").show();
|
||||
if ('speakers' in model_settings) {
|
||||
$('#coqui_api_model_settings').show();
|
||||
$('#coqui_api_model_settings_speaker').show();
|
||||
$('#coqui_api_model_settings_speaker')
|
||||
.find('option')
|
||||
.remove()
|
||||
@ -512,75 +512,75 @@ class CoquiTtsProvider {
|
||||
.append('<option value="none">Select speaker</option>')
|
||||
.val('none');
|
||||
|
||||
for (let i = 0; i < model_settings["speakers"].length; i++) {
|
||||
const speaker_label = JSON.stringify(model_settings["speakers"][i]).replaceAll("\"", "");
|
||||
$("#coqui_api_model_settings_speaker").append(new Option(speaker_label, i));
|
||||
for (let i = 0; i < model_settings['speakers'].length; i++) {
|
||||
const speaker_label = JSON.stringify(model_settings['speakers'][i]).replaceAll('"', '');
|
||||
$('#coqui_api_model_settings_speaker').append(new Option(speaker_label, i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$("#coqui_api_model_settings_speaker").hide();
|
||||
$('#coqui_api_model_settings_speaker').hide();
|
||||
}
|
||||
|
||||
$("#coqui_api_model_install_status").text("Requesting model to extras server...");
|
||||
$("#coqui_api_model_install_status").show();
|
||||
$('#coqui_api_model_install_status').text('Requesting model to extras server...');
|
||||
$('#coqui_api_model_install_status').show();
|
||||
|
||||
// Check if already installed and propose to do it otherwise
|
||||
const model_id = modelDict[model_language][model_dataset][model_name]["id"]
|
||||
console.debug(DEBUG_PREFIX,"Check if model is already installed",model_id);
|
||||
const model_id = modelDict[model_language][model_dataset][model_name]['id']
|
||||
console.debug(DEBUG_PREFIX,'Check if model is already installed',model_id);
|
||||
let result = await CoquiTtsProvider.checkmodel_state(model_id);
|
||||
result = await result.json();
|
||||
const model_state = result["model_state"];
|
||||
const model_state = result['model_state'];
|
||||
|
||||
console.debug(DEBUG_PREFIX, " Model state:", model_state)
|
||||
console.debug(DEBUG_PREFIX, ' Model state:', model_state)
|
||||
|
||||
if (model_state == "installed") {
|
||||
$("#coqui_api_model_install_status").text("Model already installed on extras server");
|
||||
$("#coqui_api_model_install_button").hide();
|
||||
if (model_state == 'installed') {
|
||||
$('#coqui_api_model_install_status').text('Model already installed on extras server');
|
||||
$('#coqui_api_model_install_button').hide();
|
||||
}
|
||||
else {
|
||||
let action = "download"
|
||||
if (model_state == "corrupted") {
|
||||
action = "repare"
|
||||
let action = 'download'
|
||||
if (model_state == 'corrupted') {
|
||||
action = 'repare'
|
||||
//toastr.error("Click install button to reinstall the model "+$("#coqui_api_model_name").find(":selected").text(), DEBUG_PREFIX+" corrupted model install", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
$("#coqui_api_model_install_status").text("Model found but incomplete try install again (maybe still downloading)"); // (remove and download again)
|
||||
$('#coqui_api_model_install_status').text('Model found but incomplete try install again (maybe still downloading)'); // (remove and download again)
|
||||
}
|
||||
else {
|
||||
toastr.info("Click download button to install the model " + $("#coqui_api_model_name").find(":selected").text(), DEBUG_PREFIX + " model not installed", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
$("#coqui_api_model_install_status").text("Model not found on extras server");
|
||||
toastr.info('Click download button to install the model ' + $('#coqui_api_model_name').find(':selected').text(), DEBUG_PREFIX + ' model not installed', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
$('#coqui_api_model_install_status').text('Model not found on extras server');
|
||||
}
|
||||
|
||||
const onModelNameChange_pointer = this.onModelNameChange;
|
||||
|
||||
$("#coqui_api_model_install_button").off("click").on("click", async function () {
|
||||
$('#coqui_api_model_install_button').off('click').on('click', async function () {
|
||||
try {
|
||||
$("#coqui_api_model_install_status").text("Downloading model...");
|
||||
$("#coqui_api_model_install_button").hide();
|
||||
$('#coqui_api_model_install_status').text('Downloading model...');
|
||||
$('#coqui_api_model_install_button').hide();
|
||||
//toastr.info("For model "+model_id, DEBUG_PREFIX+" Started "+action, { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
let apiResult = await CoquiTtsProvider.installModel(model_id, action);
|
||||
apiResult = await apiResult.json();
|
||||
|
||||
console.debug(DEBUG_PREFIX, "Response:", apiResult);
|
||||
console.debug(DEBUG_PREFIX, 'Response:', apiResult);
|
||||
|
||||
if (apiResult["status"] == "done") {
|
||||
$("#coqui_api_model_install_status").text("Model installed and ready to use!");
|
||||
$("#coqui_api_model_install_button").hide();
|
||||
if (apiResult['status'] == 'done') {
|
||||
$('#coqui_api_model_install_status').text('Model installed and ready to use!');
|
||||
$('#coqui_api_model_install_button').hide();
|
||||
onModelNameChange_pointer();
|
||||
}
|
||||
|
||||
if (apiResult["status"] == "downloading") {
|
||||
toastr.error("Check extras console for progress", DEBUG_PREFIX + " already downloading", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
$("#coqui_api_model_install_status").text("Already downloading a model, check extras console!");
|
||||
$("#coqui_api_model_install_button").show();
|
||||
if (apiResult['status'] == 'downloading') {
|
||||
toastr.error('Check extras console for progress', DEBUG_PREFIX + ' already downloading', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
$('#coqui_api_model_install_status').text('Already downloading a model, check extras console!');
|
||||
$('#coqui_api_model_install_button').show();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
toastr.error(error, DEBUG_PREFIX + " error with model download", { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
toastr.error(error, DEBUG_PREFIX + ' error with model download', { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true });
|
||||
onModelNameChange_pointer();
|
||||
}
|
||||
// will refresh model status
|
||||
});
|
||||
|
||||
$("#coqui_api_model_install_button").show();
|
||||
$('#coqui_api_model_install_button').show();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -606,7 +606,7 @@ class CoquiTtsProvider {
|
||||
'Cache-Control': 'no-cache'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"model_id": model_id,
|
||||
'model_id': model_id,
|
||||
})
|
||||
});
|
||||
|
||||
@ -630,8 +630,8 @@ class CoquiTtsProvider {
|
||||
'Cache-Control': 'no-cache'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"model_id": model_id,
|
||||
"action": action
|
||||
'model_id': model_id,
|
||||
'action': action
|
||||
})
|
||||
});
|
||||
|
||||
@ -658,8 +658,8 @@ class CoquiTtsProvider {
|
||||
'Cache-Control': 'no-cache'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"model_id": "model_id",
|
||||
"action": "action"
|
||||
'model_id': 'model_id',
|
||||
'action': 'action'
|
||||
})
|
||||
})
|
||||
|
||||
@ -683,18 +683,18 @@ class CoquiTtsProvider {
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/text-to-speech/coqui/generate-tts';
|
||||
|
||||
let language = "none"
|
||||
let speaker = "none"
|
||||
const tokens = voiceId.replaceAll("]", "").replaceAll("\"", "").split("[");
|
||||
let language = 'none'
|
||||
let speaker = 'none'
|
||||
const tokens = voiceId.replaceAll(']', '').replaceAll('"', '').split('[');
|
||||
const model_id = tokens[0]
|
||||
|
||||
console.debug(DEBUG_PREFIX, "Preparing TTS request for", tokens)
|
||||
console.debug(DEBUG_PREFIX, 'Preparing TTS request for', tokens)
|
||||
|
||||
// First option
|
||||
if (tokens.length > 1) {
|
||||
const option1 = tokens[1]
|
||||
|
||||
if (model_id.includes("multilingual"))
|
||||
if (model_id.includes('multilingual'))
|
||||
language = option1
|
||||
else
|
||||
speaker = option1
|
||||
@ -711,10 +711,10 @@ class CoquiTtsProvider {
|
||||
'Cache-Control': 'no-cache'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"text": text,
|
||||
"model_id": model_id,
|
||||
"language_id": parseInt(language),
|
||||
"speaker_id": parseInt(speaker)
|
||||
'text': text,
|
||||
'model_id': model_id,
|
||||
'language_id': parseInt(language),
|
||||
'speaker_id': parseInt(speaker)
|
||||
})
|
||||
});
|
||||
|
||||
@ -753,9 +753,9 @@ async function initLocalModels() {
|
||||
let result = await CoquiTtsProvider.getLocalModelList();
|
||||
result = await result.json();
|
||||
|
||||
coquiLocalModels = result["models_list"];
|
||||
coquiLocalModels = result['models_list'];
|
||||
|
||||
$("#coqui_local_model_name").show();
|
||||
$('#coqui_local_model_name').show();
|
||||
$('#coqui_local_model_name')
|
||||
.find('option')
|
||||
.remove()
|
||||
@ -764,7 +764,7 @@ async function initLocalModels() {
|
||||
.val('none');
|
||||
|
||||
for (const model_dataset of coquiLocalModels)
|
||||
$("#coqui_local_model_name").append(new Option(model_dataset, model_dataset));
|
||||
$('#coqui_local_model_name').append(new Option(model_dataset, model_dataset));
|
||||
|
||||
coquiLocalModelsReceived = true;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { getRequestHeaders } from "../../../script.js"
|
||||
import { getApiUrl } from "../../extensions.js"
|
||||
import { doExtrasFetch, modules } from "../../extensions.js"
|
||||
import { getPreviewString } from "./index.js"
|
||||
import { saveTtsProviderSettings } from "./index.js"
|
||||
import { getRequestHeaders } from '../../../script.js'
|
||||
import { getApiUrl } from '../../extensions.js'
|
||||
import { doExtrasFetch, modules } from '../../extensions.js'
|
||||
import { getPreviewString } from './index.js'
|
||||
import { saveTtsProviderSettings } from './index.js'
|
||||
|
||||
export { EdgeTtsProvider }
|
||||
|
||||
@ -37,7 +37,7 @@ class EdgeTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Pupulate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
@ -53,10 +53,10 @@ class EdgeTtsProvider {
|
||||
|
||||
$('#edge_tts_rate').val(this.settings.rate || 0);
|
||||
$('#edge_tts_rate_output').text(this.settings.rate || 0);
|
||||
$('#edge_tts_rate').on("input", () => {this.onSettingsChange()})
|
||||
$('#edge_tts_rate').on('input', () => {this.onSettingsChange()})
|
||||
await this.checkReady()
|
||||
|
||||
console.debug("EdgeTTS: Settings loaded")
|
||||
console.debug('EdgeTTS: Settings loaded')
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ class EdgeTtsProvider {
|
||||
throwIfModuleMissing()
|
||||
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = `/api/edge-tts/list`
|
||||
url.pathname = '/api/edge-tts/list'
|
||||
const response = await doExtrasFetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${await response.text()}`)
|
||||
@ -133,15 +133,15 @@ class EdgeTtsProvider {
|
||||
|
||||
console.info(`Generating new TTS for voice_id ${voiceId}`)
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = `/api/edge-tts/generate`;
|
||||
url.pathname = '/api/edge-tts/generate';
|
||||
const response = await doExtrasFetch(url,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
"text": inputText,
|
||||
"voice": voiceId,
|
||||
"rate": Number(this.settings.rate),
|
||||
'text': inputText,
|
||||
'voice': voiceId,
|
||||
'rate': Number(this.settings.rate),
|
||||
})
|
||||
}
|
||||
)
|
||||
@ -154,7 +154,7 @@ class EdgeTtsProvider {
|
||||
}
|
||||
function throwIfModuleMissing() {
|
||||
if (!modules.includes('edge-tts')) {
|
||||
const message = `Edge TTS module not loaded. Add edge-tts to enable-modules and restart the Extras API.`
|
||||
const message = 'Edge TTS module not loaded. Add edge-tts to enable-modules and restart the Extras API.'
|
||||
// toastr.error(message)
|
||||
throw new Error(message)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { saveTtsProviderSettings } from "./index.js"
|
||||
import { saveTtsProviderSettings } from './index.js'
|
||||
export { ElevenLabsTtsProvider }
|
||||
|
||||
class ElevenLabsTtsProvider {
|
||||
@ -14,7 +14,7 @@ class ElevenLabsTtsProvider {
|
||||
defaultSettings = {
|
||||
stability: 0.75,
|
||||
similarity_boost: 0.75,
|
||||
apiKey: "",
|
||||
apiKey: '',
|
||||
model: 'eleven_monolingual_v1',
|
||||
voiceMap: {}
|
||||
}
|
||||
@ -53,7 +53,7 @@ class ElevenLabsTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Pupulate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
@ -86,9 +86,9 @@ class ElevenLabsTtsProvider {
|
||||
|
||||
try {
|
||||
await this.checkReady()
|
||||
console.debug("ElevenLabs: Settings loaded")
|
||||
console.debug('ElevenLabs: Settings loaded')
|
||||
} catch {
|
||||
console.debug("ElevenLabs: Settings loaded, but not ready")
|
||||
console.debug('ElevenLabs: Settings loaded, but not ready')
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ class ElevenLabsTtsProvider {
|
||||
this.settings.apiKey = $('#elevenlabs_tts_api_key').val()
|
||||
|
||||
await this.fetchTtsVoiceObjects().catch(error => {
|
||||
throw `TTS API key validation failed`
|
||||
throw 'TTS API key validation failed'
|
||||
})
|
||||
console.debug(`Saved new API_KEY: ${this.settings.apiKey}`)
|
||||
$('#tts_status').text('')
|
||||
@ -146,7 +146,7 @@ class ElevenLabsTtsProvider {
|
||||
console.debug(`Found existing TTS generation with id ${historyId}`)
|
||||
response = await this.fetchTtsFromHistory(historyId)
|
||||
} else {
|
||||
console.debug(`No existing TTS generation found, requesting new generation`)
|
||||
console.debug('No existing TTS generation found, requesting new generation')
|
||||
response = await this.fetchTtsGeneration(text, voiceId)
|
||||
}
|
||||
return response
|
||||
@ -177,7 +177,7 @@ class ElevenLabsTtsProvider {
|
||||
const headers = {
|
||||
'xi-api-key': this.settings.apiKey
|
||||
}
|
||||
const response = await fetch(`https://api.elevenlabs.io/v1/voices`, {
|
||||
const response = await fetch('https://api.elevenlabs.io/v1/voices', {
|
||||
headers: headers
|
||||
})
|
||||
if (!response.ok) {
|
||||
@ -192,7 +192,7 @@ class ElevenLabsTtsProvider {
|
||||
'xi-api-key': this.settings.apiKey
|
||||
}
|
||||
const response = await fetch(
|
||||
`https://api.elevenlabs.io/v1/voices/settings/default`,
|
||||
'https://api.elevenlabs.io/v1/voices/settings/default',
|
||||
{
|
||||
headers: headers
|
||||
}
|
||||
@ -204,7 +204,7 @@ class ElevenLabsTtsProvider {
|
||||
}
|
||||
|
||||
async fetchTtsGeneration(text, voiceId) {
|
||||
let model = this.settings.model ?? "eleven_monolingual_v1";
|
||||
let model = this.settings.model ?? 'eleven_monolingual_v1';
|
||||
console.info(`Generating new TTS for voice_id ${voiceId}, model ${model}`)
|
||||
const response = await fetch(
|
||||
`https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`,
|
||||
@ -251,7 +251,7 @@ class ElevenLabsTtsProvider {
|
||||
const headers = {
|
||||
'xi-api-key': this.settings.apiKey
|
||||
}
|
||||
const response = await fetch(`https://api.elevenlabs.io/v1/history`, {
|
||||
const response = await fetch('https://api.elevenlabs.io/v1/history', {
|
||||
headers: headers
|
||||
})
|
||||
if (!response.ok) {
|
||||
|
@ -10,7 +10,7 @@ import { NovelTtsProvider } from './novel.js'
|
||||
import { power_user } from '../../power-user.js'
|
||||
import { registerSlashCommand } from '../../slash-commands.js'
|
||||
import { OpenAITtsProvider } from './openai.js'
|
||||
import {XTTSTtsProvider} from "./xtts.js"
|
||||
import {XTTSTtsProvider} from './xtts.js'
|
||||
export { talkingAnimation };
|
||||
|
||||
const UPDATE_INTERVAL = 1000
|
||||
@ -30,13 +30,13 @@ export function getPreviewString(lang) {
|
||||
'en-GB': 'Sphinx of black quartz, judge my vow',
|
||||
'fr-FR': 'Portez ce vieux whisky au juge blond qui fume',
|
||||
'de-DE': 'Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich',
|
||||
'it-IT': "Pranzo d'acqua fa volti sghembi",
|
||||
'it-IT': 'Pranzo d\'acqua fa volti sghembi',
|
||||
'es-ES': 'Quiere la boca exhausta vid, kiwi, piña y fugaz jamón',
|
||||
'es-MX': 'Fabio me exige, sin tapujos, que añada cerveza al whisky',
|
||||
'ru-RU': 'В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!',
|
||||
'pt-BR': 'Vejo xá gritando que fez show sem playback.',
|
||||
'pt-PR': 'Todo pajé vulgar faz boquinha sexy com kiwi.',
|
||||
'uk-UA': "Фабрикуймо гідність, лящім їжею, ґав хапаймо, з'єднавці чаш!",
|
||||
'uk-UA': 'Фабрикуймо гідність, лящім їжею, ґав хапаймо, з\'єднавці чаш!',
|
||||
'pl-PL': 'Pchnąć w tę łódź jeża lub ośm skrzyń fig',
|
||||
'cs-CZ': 'Příliš žluťoučký kůň úpěl ďábelské ódy',
|
||||
'sk-SK': 'Vyhŕňme si rukávy a vyprážajme čínske ryžové cestoviny',
|
||||
@ -227,16 +227,16 @@ async function moduleWorker() {
|
||||
|
||||
function talkingAnimation(switchValue) {
|
||||
if (!modules.includes('talkinghead')) {
|
||||
console.debug("Talking Animation module not loaded");
|
||||
console.debug('Talking Animation module not loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
const apiUrl = getApiUrl();
|
||||
const animationType = switchValue ? "start" : "stop";
|
||||
const animationType = switchValue ? 'start' : 'stop';
|
||||
|
||||
if (switchValue !== storedvalue) {
|
||||
try {
|
||||
console.log(animationType + " Talking Animation");
|
||||
console.log(animationType + ' Talking Animation');
|
||||
doExtrasFetch(`${apiUrl}/api/talkinghead/${animationType}_talking`);
|
||||
storedvalue = switchValue; // Update the storedvalue to the current switchValue
|
||||
} catch (error) {
|
||||
@ -283,16 +283,16 @@ function isTtsProcessing() {
|
||||
function debugTtsPlayback() {
|
||||
console.log(JSON.stringify(
|
||||
{
|
||||
"ttsProviderName": ttsProviderName,
|
||||
"voiceMap": voiceMap,
|
||||
"currentMessageNumber": currentMessageNumber,
|
||||
"audioPaused": audioPaused,
|
||||
"audioJobQueue": audioJobQueue,
|
||||
"currentAudioJob": currentAudioJob,
|
||||
"audioQueueProcessorReady": audioQueueProcessorReady,
|
||||
"ttsJobQueue": ttsJobQueue,
|
||||
"currentTtsJob": currentTtsJob,
|
||||
"ttsConfig": extension_settings.tts
|
||||
'ttsProviderName': ttsProviderName,
|
||||
'voiceMap': voiceMap,
|
||||
'currentMessageNumber': currentMessageNumber,
|
||||
'audioPaused': audioPaused,
|
||||
'audioJobQueue': audioJobQueue,
|
||||
'currentAudioJob': currentAudioJob,
|
||||
'audioQueueProcessorReady': audioQueueProcessorReady,
|
||||
'ttsJobQueue': ttsJobQueue,
|
||||
'currentTtsJob': currentTtsJob,
|
||||
'ttsConfig': extension_settings.tts
|
||||
}
|
||||
))
|
||||
}
|
||||
@ -314,7 +314,7 @@ let audioQueueProcessorReady = true
|
||||
async function playAudioData(audioBlob) {
|
||||
// Since current audio job can be cancelled, don't playback if it is null
|
||||
if (currentAudioJob == null) {
|
||||
console.log("Cancelled TTS playback because currentAudioJob was null")
|
||||
console.log('Cancelled TTS playback because currentAudioJob was null')
|
||||
}
|
||||
const reader = new FileReader()
|
||||
reader.onload = function (e) {
|
||||
@ -324,7 +324,7 @@ async function playAudioData(audioBlob) {
|
||||
reader.readAsDataURL(audioBlob)
|
||||
audioElement.addEventListener('ended', completeCurrentAudioJob)
|
||||
audioElement.addEventListener('canplay', () => {
|
||||
console.debug(`Starting TTS playback`)
|
||||
console.debug('Starting TTS playback')
|
||||
audioElement.play()
|
||||
})
|
||||
}
|
||||
@ -572,7 +572,7 @@ function loadSettings() {
|
||||
const defaultSettings = {
|
||||
voiceMap: '',
|
||||
ttsEnabled: false,
|
||||
currentProvider: "ElevenLabs",
|
||||
currentProvider: 'ElevenLabs',
|
||||
auto_generation: true,
|
||||
narrate_user: false,
|
||||
}
|
||||
@ -645,7 +645,7 @@ function onNarrateTranslatedOnlyClick() {
|
||||
|
||||
async function loadTtsProvider(provider) {
|
||||
//Clear the current config and add new config
|
||||
$("#tts_provider_settings").html("")
|
||||
$('#tts_provider_settings').html('')
|
||||
|
||||
if (!provider) {
|
||||
return
|
||||
@ -858,7 +858,7 @@ export async function initVoiceMap(unrestricted = false) {
|
||||
return
|
||||
}
|
||||
|
||||
setTtsStatus("TTS Provider Loaded", true)
|
||||
setTtsStatus('TTS Provider Loaded', true)
|
||||
|
||||
// Clear existing voiceMap state
|
||||
$('#tts_voicemap_block').empty()
|
||||
@ -869,12 +869,12 @@ export async function initVoiceMap(unrestricted = false) {
|
||||
|
||||
// Get saved voicemap from provider settings, handling new and old representations
|
||||
let voiceMapFromSettings = {}
|
||||
if ("voiceMap" in extension_settings.tts[ttsProviderName]) {
|
||||
if ('voiceMap' in extension_settings.tts[ttsProviderName]) {
|
||||
// Handle previous representation
|
||||
if (typeof extension_settings.tts[ttsProviderName].voiceMap === "string") {
|
||||
if (typeof extension_settings.tts[ttsProviderName].voiceMap === 'string') {
|
||||
voiceMapFromSettings = parseVoiceMap(extension_settings.tts[ttsProviderName].voiceMap)
|
||||
// Handle new representation
|
||||
} else if (typeof extension_settings.tts[ttsProviderName].voiceMap === "object") {
|
||||
} else if (typeof extension_settings.tts[ttsProviderName].voiceMap === 'object') {
|
||||
voiceMapFromSettings = extension_settings.tts[ttsProviderName].voiceMap
|
||||
}
|
||||
}
|
||||
@ -885,12 +885,12 @@ export async function initVoiceMap(unrestricted = false) {
|
||||
voiceIdsFromProvider = await ttsProvider.fetchTtsVoiceObjects()
|
||||
}
|
||||
catch {
|
||||
toastr.error("TTS Provider failed to return voice ids.")
|
||||
toastr.error('TTS Provider failed to return voice ids.')
|
||||
}
|
||||
|
||||
// Build UI using VoiceMapEntry objects
|
||||
for (const character of characters) {
|
||||
if (character === "SillyTavern System") {
|
||||
if (character === 'SillyTavern System') {
|
||||
continue
|
||||
}
|
||||
// Check provider settings for voiceIds
|
||||
@ -976,7 +976,7 @@ $(document).ready(function () {
|
||||
$('#tts_narrate_user').on('click', onNarrateUserClick);
|
||||
$('#tts_voices').on('click', onTtsVoicesClick)
|
||||
for (const provider in ttsProviders) {
|
||||
$('#tts_provider').append($("<option />").val(provider).text(provider))
|
||||
$('#tts_provider').append($('<option />').val(provider).text(provider))
|
||||
}
|
||||
$('#tts_provider').on('change', onTtsProviderChange)
|
||||
$(document).on('click', '.mes_narrate', onNarrateOneMessage);
|
||||
@ -991,6 +991,6 @@ $(document).ready(function () {
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged)
|
||||
eventSource.on(event_types.MESSAGE_DELETED, onChatDeleted);
|
||||
eventSource.on(event_types.GROUP_UPDATED, onChatChanged)
|
||||
registerSlashCommand('speak', onNarrateText, ['narrate', 'tts'], `<span class="monospace">(text)</span> – narrate any text using currently selected character's voice. Use voice="Character Name" argument to set other voice from the voice map, example: <tt>/speak voice="Donald Duck" Quack!</tt>`, true, true);
|
||||
registerSlashCommand('speak', onNarrateText, ['narrate', 'tts'], '<span class="monospace">(text)</span> – narrate any text using currently selected character\'s voice. Use voice="Character Name" argument to set other voice from the voice map, example: <tt>/speak voice="Donald Duck" Quack!</tt>', true, true);
|
||||
document.body.appendChild(audioElement);
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { getRequestHeaders, callPopup } from "../../../script.js"
|
||||
import { getPreviewString, saveTtsProviderSettings } from "./index.js"
|
||||
import { initVoiceMap } from "./index.js"
|
||||
import { getRequestHeaders, callPopup } from '../../../script.js'
|
||||
import { getPreviewString, saveTtsProviderSettings } from './index.js'
|
||||
import { initVoiceMap } from './index.js'
|
||||
|
||||
export { NovelTtsProvider }
|
||||
|
||||
@ -62,7 +62,7 @@ class NovelTtsProvider {
|
||||
|
||||
// Delete selected custom voice from provider
|
||||
deleteCustomVoice() {
|
||||
const selected = $("#tts-novel-custom-voices-select").find(':selected').val();
|
||||
const selected = $('#tts-novel-custom-voices-select').find(':selected').val();
|
||||
const voiceIndex = this.settings.customVoices.indexOf(selected);
|
||||
|
||||
if (voiceIndex !== -1) {
|
||||
@ -75,7 +75,7 @@ class NovelTtsProvider {
|
||||
|
||||
// Create the UI dropdown list of voices in provider
|
||||
populateCustomVoices(){
|
||||
let voiceSelect = $("#tts-novel-custom-voices-select")
|
||||
let voiceSelect = $('#tts-novel-custom-voices-select')
|
||||
voiceSelect.empty()
|
||||
this.settings.customVoices.forEach(voice => {
|
||||
voiceSelect.append(`<option>${voice}</option>`)
|
||||
@ -85,10 +85,10 @@ class NovelTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Populate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
$("#tts-novel-custom-voices-add").on('click', () => (this.addCustomVoice()))
|
||||
$("#tts-novel-custom-voices-delete").on('click',() => (this.deleteCustomVoice()))
|
||||
$('#tts-novel-custom-voices-add').on('click', () => (this.addCustomVoice()))
|
||||
$('#tts-novel-custom-voices-delete').on('click',() => (this.deleteCustomVoice()))
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
this.settings = this.defaultSettings
|
||||
@ -103,7 +103,7 @@ class NovelTtsProvider {
|
||||
|
||||
this.populateCustomVoices()
|
||||
await this.checkReady()
|
||||
console.debug("NovelTTS: Settings loaded")
|
||||
console.debug('NovelTTS: Settings loaded')
|
||||
}
|
||||
|
||||
// Perform a simple readiness check by trying to fetch voiceIds
|
||||
@ -122,7 +122,7 @@ class NovelTtsProvider {
|
||||
|
||||
async getVoice(voiceName) {
|
||||
if (!voiceName) {
|
||||
throw `TTS Voice name not provided`
|
||||
throw 'TTS Voice name not provided'
|
||||
}
|
||||
|
||||
return { name: voiceName, voice_id: voiceName, lang: 'en-US', preview_url: false}
|
||||
@ -181,13 +181,13 @@ class NovelTtsProvider {
|
||||
|
||||
async fetchTtsGeneration(inputText, voiceId) {
|
||||
console.info(`Generating new TTS for voice_id ${voiceId}`)
|
||||
const response = await fetch(`/api/novelai/generate-voice`,
|
||||
const response = await fetch('/api/novelai/generate-voice',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
"text": inputText,
|
||||
"voice": voiceId,
|
||||
'text': inputText,
|
||||
'voice': voiceId,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { getRequestHeaders } from "../../../script.js"
|
||||
import { saveTtsProviderSettings } from "./index.js";
|
||||
import { getRequestHeaders } from '../../../script.js'
|
||||
import { saveTtsProviderSettings } from './index.js';
|
||||
|
||||
export { OpenAITtsProvider }
|
||||
|
||||
@ -52,7 +52,7 @@ class OpenAITtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Populate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
@ -79,7 +79,7 @@ class OpenAITtsProvider {
|
||||
$('#openai-tts-speed-output').text(this.settings.speed);
|
||||
|
||||
await this.checkReady();
|
||||
console.debug("OpenAI TTS: Settings loaded");
|
||||
console.debug('OpenAI TTS: Settings loaded');
|
||||
}
|
||||
|
||||
onSettingsChange() {
|
||||
@ -100,7 +100,7 @@ class OpenAITtsProvider {
|
||||
|
||||
async getVoice(voiceName) {
|
||||
if (!voiceName) {
|
||||
throw `TTS Voice name not provided`
|
||||
throw 'TTS Voice name not provided'
|
||||
}
|
||||
|
||||
const voice = OpenAITtsProvider.voices.find(voice => voice.voice_id === voiceName || voice.name === voiceName);
|
||||
@ -127,14 +127,14 @@ class OpenAITtsProvider {
|
||||
|
||||
async fetchTtsGeneration(inputText, voiceId) {
|
||||
console.info(`Generating new TTS for voice_id ${voiceId}`)
|
||||
const response = await fetch(`/api/openai/generate-voice`, {
|
||||
const response = await fetch('/api/openai/generate-voice', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
"text": inputText,
|
||||
"voice": voiceId,
|
||||
"model": this.settings.model,
|
||||
"speed": this.settings.speed,
|
||||
'text': inputText,
|
||||
'voice': voiceId,
|
||||
'model': this.settings.model,
|
||||
'speed': this.settings.speed,
|
||||
}),
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { doExtrasFetch, getApiUrl, modules } from "../../extensions.js"
|
||||
import { saveTtsProviderSettings } from "./index.js"
|
||||
import { doExtrasFetch, getApiUrl, modules } from '../../extensions.js'
|
||||
import { saveTtsProviderSettings } from './index.js'
|
||||
|
||||
export { SileroTtsProvider }
|
||||
|
||||
@ -14,7 +14,7 @@ class SileroTtsProvider {
|
||||
separator = ' .. '
|
||||
|
||||
defaultSettings = {
|
||||
provider_endpoint: "http://localhost:8001/tts",
|
||||
provider_endpoint: 'http://localhost:8001/tts',
|
||||
voiceMap: {}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ class SileroTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Pupulate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
@ -64,12 +64,12 @@ class SileroTtsProvider {
|
||||
}, 2000);
|
||||
|
||||
$('#silero_tts_endpoint').val(this.settings.provider_endpoint)
|
||||
$('#silero_tts_endpoint').on("input", () => { this.onSettingsChange() })
|
||||
$('#silero_tts_endpoint').on('input', () => { this.onSettingsChange() })
|
||||
this.refreshSession()
|
||||
|
||||
await this.checkReady()
|
||||
|
||||
console.debug("SileroTTS: Settings loaded")
|
||||
console.debug('SileroTTS: Settings loaded')
|
||||
}
|
||||
|
||||
// Perform a simple readiness check by trying to fetch voiceIds
|
||||
@ -130,9 +130,9 @@ class SileroTtsProvider {
|
||||
'Cache-Control': 'no-cache' // Added this line to disable caching of file so new files are always played - Rolyat 7/7/23
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"text": inputText,
|
||||
"speaker": voiceId,
|
||||
"session": "sillytavern"
|
||||
'text': inputText,
|
||||
'speaker': voiceId,
|
||||
'session': 'sillytavern'
|
||||
})
|
||||
}
|
||||
)
|
||||
@ -144,7 +144,7 @@ class SileroTtsProvider {
|
||||
}
|
||||
|
||||
async initSession() {
|
||||
console.info(`Silero TTS: requesting new session`);
|
||||
console.info('Silero TTS: requesting new session');
|
||||
try {
|
||||
const response = await doExtrasFetch(
|
||||
`${this.settings.provider_endpoint}/session`,
|
||||
@ -155,7 +155,7 @@ class SileroTtsProvider {
|
||||
'Cache-Control': 'no-cache',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"path": "sillytavern",
|
||||
'path': 'sillytavern',
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { isMobile } from "../../RossAscends-mods.js";
|
||||
import { getPreviewString } from "./index.js";
|
||||
import { isMobile } from '../../RossAscends-mods.js';
|
||||
import { getPreviewString } from './index.js';
|
||||
import { talkingAnimation } from './index.js';
|
||||
import { saveTtsProviderSettings } from "./index.js"
|
||||
import { saveTtsProviderSettings } from './index.js'
|
||||
export { SystemTtsProvider }
|
||||
|
||||
/**
|
||||
@ -92,7 +92,7 @@ class SystemTtsProvider {
|
||||
|
||||
get settingsHtml() {
|
||||
if (!('speechSynthesis' in window)) {
|
||||
return "Your browser or operating system doesn't support speech synthesis";
|
||||
return 'Your browser or operating system doesn\'t support speech synthesis';
|
||||
}
|
||||
|
||||
return `<p>Uses the voices provided by your operating system</p>
|
||||
@ -113,7 +113,7 @@ class SystemTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Populate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings");
|
||||
console.info('Using default TTS Provider settings');
|
||||
}
|
||||
|
||||
// iOS should only allows speech synthesis trigged by user interaction
|
||||
@ -146,12 +146,12 @@ class SystemTtsProvider {
|
||||
$('#system_tts_pitch').val(this.settings.pitch || this.defaultSettings.pitch);
|
||||
|
||||
// Trigger updates
|
||||
$('#system_tts_rate').on("input", () => { this.onSettingsChange() })
|
||||
$('#system_tts_rate').on("input", () => { this.onSettingsChange() })
|
||||
$('#system_tts_rate').on('input', () => { this.onSettingsChange() })
|
||||
$('#system_tts_rate').on('input', () => { this.onSettingsChange() })
|
||||
|
||||
$('#system_tts_pitch_output').text(this.settings.pitch);
|
||||
$('#system_tts_rate_output').text(this.settings.rate);
|
||||
console.debug("SystemTTS: Settings loaded");
|
||||
console.debug('SystemTTS: Settings loaded');
|
||||
}
|
||||
|
||||
// Perform a simple readiness check by trying to fetch voiceIds
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { doExtrasFetch, getApiUrl, modules } from "../../extensions.js"
|
||||
import { saveTtsProviderSettings } from "./index.js"
|
||||
import { doExtrasFetch, getApiUrl, modules } from '../../extensions.js'
|
||||
import { saveTtsProviderSettings } from './index.js'
|
||||
|
||||
export { XTTSTtsProvider }
|
||||
|
||||
@ -29,28 +29,28 @@ class XTTSTtsProvider {
|
||||
}
|
||||
|
||||
languageLabels = {
|
||||
"Arabic": "ar",
|
||||
"Brazilian Portuguese": "pt",
|
||||
"Chinese": "zh-cn",
|
||||
"Czech": "cs",
|
||||
"Dutch": "nl",
|
||||
"English": "en",
|
||||
"French": "fr",
|
||||
"German": "de",
|
||||
"Italian": "it",
|
||||
"Polish": "pl",
|
||||
"Russian": "ru",
|
||||
"Spanish": "es",
|
||||
"Turkish": "tr",
|
||||
"Japanese": "ja",
|
||||
"Korean": "ko",
|
||||
"Hungarian": "hu",
|
||||
"Hindi": "hi",
|
||||
'Arabic': 'ar',
|
||||
'Brazilian Portuguese': 'pt',
|
||||
'Chinese': 'zh-cn',
|
||||
'Czech': 'cs',
|
||||
'Dutch': 'nl',
|
||||
'English': 'en',
|
||||
'French': 'fr',
|
||||
'German': 'de',
|
||||
'Italian': 'it',
|
||||
'Polish': 'pl',
|
||||
'Russian': 'ru',
|
||||
'Spanish': 'es',
|
||||
'Turkish': 'tr',
|
||||
'Japanese': 'ja',
|
||||
'Korean': 'ko',
|
||||
'Hungarian': 'hu',
|
||||
'Hindi': 'hi',
|
||||
}
|
||||
|
||||
defaultSettings = {
|
||||
provider_endpoint: "http://localhost:8020",
|
||||
language: "en",
|
||||
provider_endpoint: 'http://localhost:8020',
|
||||
language: 'en',
|
||||
voiceMap: {}
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ class XTTSTtsProvider {
|
||||
async loadSettings(settings) {
|
||||
// Pupulate Provider UI given input settings
|
||||
if (Object.keys(settings).length == 0) {
|
||||
console.info("Using default TTS Provider settings")
|
||||
console.info('Using default TTS Provider settings')
|
||||
}
|
||||
|
||||
// Only accept keys defined in defaultSettings
|
||||
@ -122,13 +122,13 @@ class XTTSTtsProvider {
|
||||
}, 2000);
|
||||
|
||||
$('#xtts_tts_endpoint').val(this.settings.provider_endpoint)
|
||||
$('#xtts_tts_endpoint').on("input", () => { this.onSettingsChange() })
|
||||
$('#xtts_tts_endpoint').on('input', () => { this.onSettingsChange() })
|
||||
$('#xtts_api_language').val(this.settings.language)
|
||||
$('#xtts_api_language').on("change", () => { this.onSettingsChange() })
|
||||
$('#xtts_api_language').on('change', () => { this.onSettingsChange() })
|
||||
|
||||
await this.checkReady()
|
||||
|
||||
console.debug("XTTS: Settings loaded")
|
||||
console.debug('XTTS: Settings loaded')
|
||||
}
|
||||
|
||||
// Perform a simple readiness check by trying to fetch voiceIds
|
||||
@ -185,9 +185,9 @@ class XTTSTtsProvider {
|
||||
'Cache-Control': 'no-cache' // Added this line to disable caching of file so new files are always played - Rolyat 7/7/23
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"text": inputText,
|
||||
"speaker_wav": voiceId,
|
||||
"language": this.settings.language
|
||||
'text': inputText,
|
||||
'speaker_wav': voiceId,
|
||||
'language': this.settings.language
|
||||
})
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user