您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
3/19/2025, 2:23:22 PM
// ==UserScript== // @name FT.live Message reader // @namespace Violentmonkey Scripts // @match https://www.fishtank.live/* // @grant none // @version 1.0 // @license AGPL-3.0 // @author Me :) // @description 3/19/2025, 2:23:22 PM // ==/UserScript== const USERNAME = 'FT_USERNAME'; const SPEECH_PITCH = 1.0; const SPEECH_RATE = 1.0; const MAX_TTS_QUEUED = 3; // If there's a bunch of messages in a row, the get queued up, if the queue is full the most recent message will be replaced const MS_BETWEEN_TTS = 3000; // Time in between TTS in milliseconds const PREFERRED_VOICES = ['Asilia', 'Aria', 'Google']; const LANGS = ['en-US', 'en-KE']; // Accepted voice languages (function() { window.playingTTS = false; window.ttsQueue = []; 'use strict'; const voices = speechSynthesis.getVoices(); function chooseVoice() { const voices = speechSynthesis.getVoices(); if (voices.length === 0) { console.log('No TTS voices available.'); return null; } let fallback = null; for (let j = 0; j < PREFERRED_VOICES.length; j++) { for (let i = 0; i < voices.length; i++) { const v = voices[i]; if (LANGS.indexOf(v.lang) === -1) continue; if (fallback === null) fallback = v; if (v.name.includes(PREFERRED_VOICES[j])) { return v; } } } return fallback || voices[0]; } function speakTextAdvanced(text, forceTTS=false) { if (window.playingTTS && !forceTTS) { if (window.ttsQueue.length >= MAX_TTS_QUEUED) { window.ttsQueue[MAX_TTS_QUEUED-1] = text; // replace last message in queue } else { window.ttsQueue.push(text); } return; } const utterance = new SpeechSynthesisUtterance(text); utterance.rate = SPEECH_RATE; // Speed (0.1 - 10, default: 1) utterance.pitch = SPEECH_PITCH; // Pitch (0 - 2, default: 1) // Get available voices and select one utterance.voice = chooseVoice(); if (utterance.voice === null) return; utterance.onend = () => { if (window.ttsQueue.length === 0) { window.playingTTS = false; } else { setTimeout(() => speakTextAdvanced(window.ttsQueue.pop(), true), MS_BETWEEN_TTS); } }; speechSynthesis.speak(utterance); window.playingTTS = true; } function processChatMessage(node) { const msgSpans = node.getElementsByClassName('chat-message-default_message__milmT'); if (msgSpans.length == 0) return; const msg = msgSpans[0].innerText.toLocaleLowerCase(); if (msg.indexOf(USERNAME.toLocaleLowerCase()) !== -1) { let cleanMsg = msg.replaceAll('@' + USERNAME, ''); cleanMsg = cleanMsg.replaceAll(USERNAME, ''); speakTextAdvanced(cleanMsg); } } // Function to handle new messages function handleNewMessage(mutationsList) { for (let mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === 1 && node.tagName === 'DIV') { processChatMessage(node); } }); } } } // Wait for the chat container to be available function waitForChatContainer() { const chatContainer = document.getElementById("chat-messages"); if (chatContainer) { const observer = new MutationObserver(handleNewMessage); observer.observe(chatContainer, { childList: true }); console.log("Observer started on #chat-messages"); } else { setTimeout(waitForChatContainer, 500); } } waitForChatContainer(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址