mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Provide option for manual generation
This commit is contained in:
@ -23,24 +23,6 @@ let ttsProviders = {
|
|||||||
}
|
}
|
||||||
let ttsProvider
|
let ttsProvider
|
||||||
let ttsProviderName
|
let ttsProviderName
|
||||||
let autoGeneration = true;
|
|
||||||
|
|
||||||
function resetTtsPlayback() {
|
|
||||||
// Clear currently processing jobs
|
|
||||||
currentTtsJob = null;
|
|
||||||
currentAudioJob = null;
|
|
||||||
|
|
||||||
// Reset audio element
|
|
||||||
audioElement.currentTime = 0;
|
|
||||||
audioElement.src = null;
|
|
||||||
|
|
||||||
// Clearn any queue items
|
|
||||||
ttsJobQueue.splice(0, ttsJobQueue.length);
|
|
||||||
audioJobQueue.splice(0, audioJobQueue.length);
|
|
||||||
|
|
||||||
// Set audio ready to process again
|
|
||||||
audioQueueProcessorReady = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onNarrateOneMessage() {
|
async function onNarrateOneMessage() {
|
||||||
cancelTtsPlay();
|
cancelTtsPlay();
|
||||||
@ -90,6 +72,12 @@ async function moduleWorker() {
|
|||||||
processAudioJobQueue()
|
processAudioJobQueue()
|
||||||
updateUiAudioPlayState()
|
updateUiAudioPlayState()
|
||||||
|
|
||||||
|
|
||||||
|
// Auto generation is disabled
|
||||||
|
if (extension_settings.tts.auto_generation == false){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// no characters or group selected
|
// no characters or group selected
|
||||||
if (!context.groupId && context.characterId === undefined) {
|
if (!context.groupId && context.characterId === undefined) {
|
||||||
return
|
return
|
||||||
@ -141,6 +129,38 @@ async function moduleWorker() {
|
|||||||
ttsJobQueue.push(message)
|
ttsJobQueue.push(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resetTtsPlayback() {
|
||||||
|
// Clear currently processing jobs
|
||||||
|
currentTtsJob = null;
|
||||||
|
currentAudioJob = null;
|
||||||
|
|
||||||
|
// Reset audio element
|
||||||
|
audioElement.currentTime = 0;
|
||||||
|
audioElement.src = null;
|
||||||
|
|
||||||
|
// Clear any queue items
|
||||||
|
ttsJobQueue.splice(0, ttsJobQueue.length);
|
||||||
|
audioJobQueue.splice(0, audioJobQueue.length);
|
||||||
|
|
||||||
|
// Set audio ready to process again
|
||||||
|
audioQueueProcessorReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTtsProcessing() {
|
||||||
|
let processing = false
|
||||||
|
|
||||||
|
// Check job queues
|
||||||
|
if (ttsJobQueue.length > 0 || audioJobQueue > 0){
|
||||||
|
processing = true
|
||||||
|
}
|
||||||
|
// Check current jobs
|
||||||
|
if (currentTtsJob != null || currentAudioJob != null) {
|
||||||
|
processing = true
|
||||||
|
}
|
||||||
|
return processing
|
||||||
|
}
|
||||||
|
|
||||||
//##################//
|
//##################//
|
||||||
// Audio Control //
|
// Audio Control //
|
||||||
//##################//
|
//##################//
|
||||||
@ -155,6 +175,10 @@ let audioQueueProcessorReady = true
|
|||||||
let lastAudioPosition = 0
|
let lastAudioPosition = 0
|
||||||
|
|
||||||
async function playAudioData(audioBlob) {
|
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")
|
||||||
|
}
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.onload = function (e) {
|
reader.onload = function (e) {
|
||||||
const srcUrl = e.target.result
|
const srcUrl = e.target.result
|
||||||
@ -199,9 +223,13 @@ async function onTtsVoicesClick() {
|
|||||||
function updateUiAudioPlayState() {
|
function updateUiAudioPlayState() {
|
||||||
if (extension_settings.tts.enabled == true) {
|
if (extension_settings.tts.enabled == true) {
|
||||||
audioControl.style.display = 'flex'
|
audioControl.style.display = 'flex'
|
||||||
const img = !audioElement.paused
|
let img
|
||||||
? 'fa-solid fa-circle-pause'
|
// Give user feedback that TTS is active by setting the stop icon if processing or playing
|
||||||
: 'fa-solid fa-circle-play'
|
if (!audioElement.paused || isTtsProcessing()){
|
||||||
|
img = 'fa-solid fa-stop-circle'
|
||||||
|
} else {
|
||||||
|
img = 'fa-solid fa-circle-play'
|
||||||
|
}
|
||||||
audioControl.className = img
|
audioControl.className = img
|
||||||
} else {
|
} else {
|
||||||
audioControl.style.display = 'none'
|
audioControl.style.display = 'none'
|
||||||
@ -209,7 +237,14 @@ function updateUiAudioPlayState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onAudioControlClicked() {
|
function onAudioControlClicked() {
|
||||||
audioElement.paused ? audioElement.play() : audioElement.pause()
|
let context = getContext()
|
||||||
|
// Not pausing, doing a full stop to anything TTS is doing. Better UX as pause is not as useful
|
||||||
|
if (!audioElement.paused || isTtsProcessing()){
|
||||||
|
resetTtsPlayback()
|
||||||
|
} else {
|
||||||
|
// Default play behavior if not processing or playing is to play the last message.
|
||||||
|
ttsJobQueue.push(context.chat[context.chat.length - 1])
|
||||||
|
}
|
||||||
updateUiAudioPlayState()
|
updateUiAudioPlayState()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +257,7 @@ function addAudioControl() {
|
|||||||
|
|
||||||
function completeCurrentAudioJob() {
|
function completeCurrentAudioJob() {
|
||||||
audioQueueProcessorReady = true
|
audioQueueProcessorReady = true
|
||||||
|
currentAudioJob = null
|
||||||
lastAudioPosition = 0
|
lastAudioPosition = 0
|
||||||
// updateUiPlayState();
|
// updateUiPlayState();
|
||||||
}
|
}
|
||||||
@ -259,7 +295,7 @@ async function processAudioJobQueue() {
|
|||||||
//################//
|
//################//
|
||||||
|
|
||||||
let ttsJobQueue = []
|
let ttsJobQueue = []
|
||||||
let currentTtsJob
|
let currentTtsJob // Null if nothing is currently being processed
|
||||||
let currentMessageNumber = 0
|
let currentMessageNumber = 0
|
||||||
|
|
||||||
function completeTtsJob() {
|
function completeTtsJob() {
|
||||||
@ -348,14 +384,15 @@ 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)
|
||||||
|
$('#tts_auto_generation').prop('checked', extension_settings.tts.auto_generation)
|
||||||
$('body').toggleClass('tts', extension_settings.tts.enabled);
|
$('body').toggleClass('tts', extension_settings.tts.enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
voiceMap: '',
|
voiceMap: '',
|
||||||
ttsEnabled: false,
|
ttsEnabled: false,
|
||||||
currentProvider: "ElevenLabs"
|
currentProvider: "ElevenLabs",
|
||||||
|
auto_generation: true
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTtsStatus(status, success) {
|
function setTtsStatus(status, success) {
|
||||||
@ -435,6 +472,11 @@ function onEnableClick() {
|
|||||||
saveSettingsDebounced()
|
saveSettingsDebounced()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAutoGenerationClick() {
|
||||||
|
extension_settings.tts.auto_generation = $('#tts_auto_generation').prop('checked');
|
||||||
|
saveSettingsDebounced()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function onNarrateDialoguesClick() {
|
function onNarrateDialoguesClick() {
|
||||||
extension_settings.tts.narrate_dialogues_only = $('#tts_narrate_dialogues').prop('checked');
|
extension_settings.tts.narrate_dialogues_only = $('#tts_narrate_dialogues').prop('checked');
|
||||||
@ -523,6 +565,10 @@ $(document).ready(function () {
|
|||||||
<input type="checkbox" id="tts_enabled" name="tts_enabled">
|
<input type="checkbox" id="tts_enabled" name="tts_enabled">
|
||||||
Enabled
|
Enabled
|
||||||
</label>
|
</label>
|
||||||
|
<label class="checkbox_label" for="tts_auto_generation">
|
||||||
|
<input type="checkbox" id="tts_auto_generation">
|
||||||
|
Auto Generation
|
||||||
|
</label>
|
||||||
<label class="checkbox_label" for="tts_narrate_dialogues">
|
<label class="checkbox_label" for="tts_narrate_dialogues">
|
||||||
<input type="checkbox" id="tts_narrate_dialogues">
|
<input type="checkbox" id="tts_narrate_dialogues">
|
||||||
Narrate dialogues only
|
Narrate dialogues only
|
||||||
@ -554,6 +600,7 @@ $(document).ready(function () {
|
|||||||
$('#tts_enabled').on('click', onEnableClick)
|
$('#tts_enabled').on('click', onEnableClick)
|
||||||
$('#tts_narrate_dialogues').on('click', onNarrateDialoguesClick);
|
$('#tts_narrate_dialogues').on('click', onNarrateDialoguesClick);
|
||||||
$('#tts_narrate_quoted').on('click', onNarrateQuotedClick);
|
$('#tts_narrate_quoted').on('click', onNarrateQuotedClick);
|
||||||
|
$('#tts_auto_generation').on('click', onAutoGenerationClick);
|
||||||
$('#tts_voices').on('click', onTtsVoicesClick)
|
$('#tts_voices').on('click', onTtsVoicesClick)
|
||||||
$('#tts_provider_settings').on('input', onTtsProviderSettingsInput)
|
$('#tts_provider_settings').on('input', onTtsProviderSettingsInput)
|
||||||
for (const provider in ttsProviders) {
|
for (const provider in ttsProviders) {
|
||||||
|
Reference in New Issue
Block a user