mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add a button to narrate only one message with TTS
This commit is contained in:
@ -2325,6 +2325,7 @@
|
|||||||
<span class="name_text">${characterName}</span>
|
<span class="name_text">${characterName}</span>
|
||||||
|
|
||||||
<div class="mes_buttons">
|
<div class="mes_buttons">
|
||||||
|
<div title="Narrate" class="mes_narrate fa-solid fa-bullhorn"></div>
|
||||||
<div title="Prompt" class="mes_prompt fa-solid fa-square-poll-horizontal "></div>
|
<div title="Prompt" class="mes_prompt fa-solid fa-square-poll-horizontal "></div>
|
||||||
<div title="Copy" class="mes_copy fa-solid fa-copy "></div>
|
<div title="Copy" class="mes_copy fa-solid fa-copy "></div>
|
||||||
<div title="Edit" class="mes_edit fa-solid fa-pencil "></div>
|
<div title="Edit" class="mes_edit fa-solid fa-pencil "></div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { callPopup, isMultigenEnabled, is_send_press, saveSettingsDebounced } from '../../../script.js'
|
import { callPopup, cancelTtsPlay, isMultigenEnabled, is_send_press, saveSettingsDebounced } from '../../../script.js'
|
||||||
import { extension_settings, getContext } from '../../extensions.js'
|
import { extension_settings, getContext } from '../../extensions.js'
|
||||||
import { getStringHash } from '../../utils.js'
|
import { getStringHash } from '../../utils.js'
|
||||||
import { ElevenLabsTtsProvider } from './elevenlabs.js'
|
import { ElevenLabsTtsProvider } from './elevenlabs.js'
|
||||||
@ -24,9 +24,47 @@ let ttsProviders = {
|
|||||||
let ttsProvider
|
let ttsProvider
|
||||||
let ttsProviderName
|
let ttsProviderName
|
||||||
|
|
||||||
|
async function onNarrateOneMessage() {
|
||||||
|
cancelTtsPlay();
|
||||||
|
const context = getContext();
|
||||||
|
const id = $(this).closest('.mes').attr('mesid');
|
||||||
|
const message = context.chat[id];
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTtsJob = null;
|
||||||
|
audioElement.pause();
|
||||||
|
audioElement.currentTime = 0;
|
||||||
|
ttsJobQueue.splice(0, ttsJobQueue.length);
|
||||||
|
audioJobQueue.splice(0, audioJobQueue.length);
|
||||||
|
ttsJobQueue.push(message);
|
||||||
|
moduleWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
let isWorkerBusy = false;
|
||||||
|
|
||||||
|
async function moduleWorkerWrapper() {
|
||||||
|
// Don't touch me I'm busy...
|
||||||
|
if (isWorkerBusy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I'm free. Let's update!
|
||||||
|
try {
|
||||||
|
isWorkerBusy = true;
|
||||||
|
await moduleWorker();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
isWorkerBusy = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function moduleWorker() {
|
async function moduleWorker() {
|
||||||
// Primarily determinign when to add new chat to the TTS queue
|
// Primarily determinign when to add new chat to the TTS queue
|
||||||
const enabled = $('#tts_enabled').is(':checked')
|
const enabled = $('#tts_enabled').is(':checked')
|
||||||
|
$('body').toggleClass('tts', enabled);
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -296,6 +334,7 @@ function loadSettings() {
|
|||||||
)
|
)
|
||||||
$('#tts_narrate_dialogues').prop('checked', extension_settings.tts.narrate_dialogues_only)
|
$('#tts_narrate_dialogues').prop('checked', extension_settings.tts.narrate_dialogues_only)
|
||||||
$('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only)
|
$('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only)
|
||||||
|
$('body').toggleClass('tts', extension_settings.tts.enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
@ -507,10 +546,11 @@ $(document).ready(function () {
|
|||||||
$('#tts_provider').append($("<option />").val(provider).text(provider))
|
$('#tts_provider').append($("<option />").val(provider).text(provider))
|
||||||
}
|
}
|
||||||
$('#tts_provider').on('change', onTtsProviderChange)
|
$('#tts_provider').on('change', onTtsProviderChange)
|
||||||
|
$(document).on('click', '.mes_narrate', onNarrateOneMessage);
|
||||||
}
|
}
|
||||||
addExtensionControls() // No init dependencies
|
addExtensionControls() // No init dependencies
|
||||||
loadSettings() // Depends on Extension Controls and loadTtsProvider
|
loadSettings() // Depends on Extension Controls and loadTtsProvider
|
||||||
loadTtsProvider(extension_settings.tts.currentProvider) // No dependencies
|
loadTtsProvider(extension_settings.tts.currentProvider) // No dependencies
|
||||||
addAudioControl() // Depends on Extension Controls
|
addAudioControl() // Depends on Extension Controls
|
||||||
setInterval(moduleWorker, UPDATE_INTERVAL) // Init depends on all the things
|
setInterval(moduleWorkerWrapper, UPDATE_INTERVAL) // Init depends on all the things
|
||||||
})
|
})
|
||||||
|
@ -203,6 +203,16 @@ table.responsiveTable {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mes_narrate,
|
||||||
|
body.tts .mes[is_user="true"] .mes_narrate,
|
||||||
|
body.tts .mes[is_system="true"] .mes_narrate {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.tts .mes_narrate {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: Consolas, monospace;
|
font-family: Consolas, monospace;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
@ -2155,6 +2165,7 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mes_prompt,
|
.mes_prompt,
|
||||||
|
.mes_narrate,
|
||||||
.mes_copy,
|
.mes_copy,
|
||||||
.mes_edit {
|
.mes_edit {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -2167,11 +2178,13 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
|
|
||||||
.mes_edit:hover,
|
.mes_edit:hover,
|
||||||
.mes_copy:hover,
|
.mes_copy:hover,
|
||||||
|
.mes_narrate:hover,
|
||||||
.mes_stop:hover {
|
.mes_stop:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.last_mes .mes_copy,
|
.last_mes .mes_copy,
|
||||||
|
.last_mes .mes_narrate,
|
||||||
.last_mes .mes_prompt {
|
.last_mes .mes_prompt {
|
||||||
grid-row-start: 1;
|
grid-row-start: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
Reference in New Issue
Block a user