Merge branch 'staging' into support-multiple-expressions

This commit is contained in:
Wolfsblvt
2025-02-01 04:47:48 +01:00
38 changed files with 1273 additions and 308 deletions

View File

@ -388,7 +388,7 @@ class AllTalkTtsProvider {
}
async fetchRvcVoiceObjects() {
if (this.settings.server_version == 'v2') {
if (this.settings.server_version == 'v1') {
console.log('Skipping RVC voices fetch for V1 server');
return [];
}
@ -1031,14 +1031,18 @@ class AllTalkTtsProvider {
console.error('fetchTtsGeneration Error Response Text:', errorText);
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
const data = await response.json();
// Handle V1/V2 URL differences
const outputUrl = this.settings.server_version === 'v1'
? data.output_file_url // V1 returns full URL
: `${this.settings.provider_endpoint}${data.output_file_url}`; // V2 returns relative path
// V1 returns a complete URL, V2 returns a relative path
if (this.settings.server_version === 'v1') {
// V1: Use the complete URL directly from the response
return data.output_file_url;
} else {
// V2: Combine the endpoint with the relative path
return `${this.settings.provider_endpoint}${data.output_file_url}`;
}
return outputUrl;
} catch (error) {
console.error('[fetchTtsGeneration] Exception caught:', error);
throw error;

View File

@ -29,6 +29,7 @@ import { POPUP_TYPE, callGenericPopup } from '../../popup.js';
import { GoogleTranslateTtsProvider } from './google-translate.js';
const UPDATE_INTERVAL = 1000;
const wrapper = new ModuleWorkerWrapper(moduleWorker);
let voiceMapEntries = [];
let voiceMap = {}; // {charName:voiceid, charName2:voiceid2}
@ -118,7 +119,7 @@ async function onNarrateOneMessage() {
}
resetTtsPlayback();
ttsJobQueue.push(message);
processAndQueueTtsMessage(message);
moduleWorker();
}
@ -145,7 +146,7 @@ async function onNarrateText(args, text) {
}
resetTtsPlayback();
ttsJobQueue.push({ mes: text, name: name });
processAndQueueTtsMessage({ mes: text, name: name });
await moduleWorker();
// Return back to the chat voices
@ -197,6 +198,36 @@ function isTtsProcessing() {
return processing;
}
/**
* Splits a message into lines and adds each non-empty line to the TTS job queue.
* @param {Object} message - The message object to be processed.
* @param {string} message.mes - The text of the message to be split into lines.
* @param {string} message.name - The name associated with the message.
* @returns {void}
*/
function processAndQueueTtsMessage(message) {
if (!extension_settings.tts.narrate_by_paragraphs) {
ttsJobQueue.push(message);
return;
}
const lines = message.mes.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.length === 0) {
continue;
}
ttsJobQueue.push(
Object.assign({}, message, {
mes: line,
}),
);
}
}
function debugTtsPlayback() {
console.log(JSON.stringify(
{
@ -326,7 +357,7 @@ function onAudioControlClicked() {
resetTtsPlayback();
} else {
// Default play behavior if not processing or playing is to play the last message.
ttsJobQueue.push(context.chat[context.chat.length - 1]);
processAndQueueTtsMessage(context.chat[context.chat.length - 1]);
}
updateUiAudioPlayState();
}
@ -351,6 +382,7 @@ function completeCurrentAudioJob() {
audioQueueProcessorReady = true;
currentAudioJob = null;
// updateUiPlayState();
wrapper.update();
}
/**
@ -440,7 +472,7 @@ async function processTtsQueue() {
}
if (extension_settings.tts.skip_tags) {
text = text.replace(/<.*?>.*?<\/.*?>/g, '').trim();
text = text.replace(/<.*?>[\s\S]*?<\/.*?>/g, '').trim();
}
if (!extension_settings.tts.pass_asterisks) {
@ -543,6 +575,7 @@ function loadSettings() {
$('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only);
$('#tts_auto_generation').prop('checked', extension_settings.tts.auto_generation);
$('#tts_periodic_auto_generation').prop('checked', extension_settings.tts.periodic_auto_generation);
$('#tts_narrate_by_paragraphs').prop('checked', extension_settings.tts.narrate_by_paragraphs);
$('#tts_narrate_translated_only').prop('checked', extension_settings.tts.narrate_translated_only);
$('#tts_narrate_user').prop('checked', extension_settings.tts.narrate_user);
$('#tts_pass_asterisks').prop('checked', extension_settings.tts.pass_asterisks);
@ -612,6 +645,11 @@ function onPeriodicAutoGenerationClick() {
saveSettingsDebounced();
}
function onNarrateByParagraphsClick() {
extension_settings.tts.narrate_by_paragraphs = !!$('#tts_narrate_by_paragraphs').prop('checked');
saveSettingsDebounced();
}
function onNarrateDialoguesClick() {
extension_settings.tts.narrate_dialogues_only = !!$('#tts_narrate_dialogues').prop('checked');
@ -790,7 +828,12 @@ async function onMessageEvent(messageId, lastCharIndex) {
lastChatId = context.chatId;
console.debug(`Adding message from ${message.name} for TTS processing: "${message.mes}"`);
ttsJobQueue.push(message);
if (extension_settings.tts.periodic_auto_generation) {
ttsJobQueue.push(message);
} else {
processAndQueueTtsMessage(message);
}
}
async function onMessageDeleted() {
@ -1130,6 +1173,7 @@ jQuery(async function () {
$('#tts_pass_asterisks').on('click', onPassAsterisksClick);
$('#tts_auto_generation').on('click', onAutoGenerationClick);
$('#tts_periodic_auto_generation').on('click', onPeriodicAutoGenerationClick);
$('#tts_narrate_by_paragraphs').on('click', onNarrateByParagraphsClick);
$('#tts_narrate_user').on('click', onNarrateUserClick);
$('#playback_rate').on('input', function () {
@ -1151,7 +1195,6 @@ jQuery(async function () {
loadSettings(); // Depends on Extension Controls and loadTtsProvider
loadTtsProvider(extension_settings.tts.currentProvider); // No dependencies
addAudioControl(); // Depends on Extension Controls
const wrapper = new ModuleWorkerWrapper(moduleWorker);
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL); // Init depends on all the things
eventSource.on(event_types.MESSAGE_SWIPED, resetTtsPlayback);
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);

View File

@ -30,6 +30,10 @@
<input type="checkbox" id="tts_periodic_auto_generation">
<small data-i18n="Narrate by paragraphs (when streaming)">Narrate by paragraphs (when streaming)</small>
</label>
<label class="checkbox_label" for="tts_narrate_by_paragraphs">
<input type="checkbox" id="tts_narrate_by_paragraphs">
<small data-i18n="Narrate by paragraphs (when not streaming)">Narrate by paragraphs (when not streaming)</small>
</label>
<label class="checkbox_label" for="tts_narrate_quoted">
<input type="checkbox" id="tts_narrate_quoted">
<small data-i18n="Only narrate quotes">Only narrate "quotes"</small>