您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add a button to each chat message to play it using TTS API
当前为
// ==UserScript== // @name vits-simple-api for SillyTavern // @namespace https://github.com/yujianke100/vits-simple-api-for-SillyTavern // @version 1.0.0 // @license MIT // @description Add a button to each chat message to play it using TTS API // @author yujianke100 // @match http://*:8080* // @match http://localhost:8080/* // @match http://127.0.0.1:8080/* // @grant GM_xmlhttpRequest // ==/UserScript== (function() { 'use strict'; let currentAudio = null; let readQuotesOnly = false; let toggleSwitches = []; // Function to add TTS, Stop buttons, and a Toggle button to each chat message function addTTSButton(message) { if (!message.querySelector('.mytts-button')) { const ttsButton = document.createElement('button'); ttsButton.innerText = 'TTS'; ttsButton.classList.add('mytts-button', 'action-button'); const stopButton = document.createElement('button'); stopButton.innerText = 'Stop'; stopButton.classList.add('stop-button', 'action-button'); const toggleButton = document.createElement('button'); toggleButton.innerText = readQuotesOnly ? 'Quotes' : 'Full Text'; toggleButton.classList.add('toggle-button', 'action-button'); updateToggleButtonStyle(toggleButton); const handleToggleChange = () => { readQuotesOnly = !readQuotesOnly; console.log('Read Quotes Only:', readQuotesOnly); toggleSwitches.forEach(btn => { btn.innerText = readQuotesOnly ? 'Quotes' : 'Full Text'; updateToggleButtonStyle(btn); }); }; toggleButton.addEventListener('click', handleToggleChange); toggleSwitches.push(toggleButton); ttsButton.addEventListener('click', () => { console.log('TTS button clicked'); let messageText = message.querySelector('.mes_text').innerText; if (readQuotesOnly) { const quotes = messageText.match(/“([^”]*)”/g); messageText = quotes ? quotes.map(quote => quote.replace(/“|”/g, '')).join(' ') : ''; } console.log('TTS for:', messageText); playTTS(messageText, ttsButton); }); stopButton.addEventListener('click', () => { if (currentAudio) { currentAudio.pause(); currentAudio.currentTime = 0; console.log('Audio stopped'); updateTTSButtonStyle(null); } }); const buttonsContainer = message.querySelector('.mes_buttons'); if (buttonsContainer) { buttonsContainer.appendChild(toggleButton); buttonsContainer.appendChild(ttsButton); buttonsContainer.appendChild(stopButton); console.log('TTS, Stop buttons, and Toggle button added'); } } } // Function to update the toggle button style function updateToggleButtonStyle(button) { if (readQuotesOnly) { button.style.backgroundColor = 'green'; button.style.color = 'white'; } else { button.style.backgroundColor = 'white'; button.style.color = 'black'; } } // Function to update the TTS button style function updateTTSButtonStyle(button) { document.querySelectorAll('.mytts-button').forEach(btn => { btn.style.backgroundColor = btn === button ? 'green' : ''; btn.style.color = btn === button ? 'white' : ''; }); } // Function to send text to TTS API and play response function playTTS(text, ttsButton) { console.log('Sending text to TTS API:', text); const apiUrl = `http://127.0.0.1:23456/voice/bert-vits2?text=${encodeURIComponent(text)}&id=0&noise=0.5&noisew=0.5`; GM_xmlhttpRequest({ method: 'GET', url: apiUrl, responseType: 'blob', // Expecting a binary response onload: function(response) { // Convert the response Blob to a URL const audioUrl = URL.createObjectURL(response.response); if (currentAudio) { currentAudio.pause(); currentAudio.currentTime = 0; } currentAudio = new Audio(audioUrl); currentAudio.play().catch(e => console.error('Audio play error:', e)); currentAudio.onplay = () => updateTTSButtonStyle(ttsButton); currentAudio.onpause = () => updateTTSButtonStyle(null); currentAudio.onended = () => updateTTSButtonStyle(null); }, onerror: function(error) { console.error('TTS API Error:', error); } }); } // Adding CSS styles for the buttons const style = document.createElement('style'); style.innerHTML = ` .action-button { background-color: gray; color: white; border: none; padding: 5px 10px; margin: 2px; cursor: pointer; } .action-button:hover { background-color: lightgray; } .mytts-button.playing { background-color: green; } `; document.head.appendChild(style); // Using MutationObserver to dynamically add buttons to new messages const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.addedNodes) { mutation.addedNodes.forEach(node => { if (node.classList && node.classList.contains('mes')) { addTTSButton(node); } }); } }); }); // Start observing const config = { childList: true, subtree: true }; observer.observe(document.body, config); })();