您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
tts
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/534400/1580094/ttsspeak.js
- ;(() => {
- let vices = [], utterance, vice, viceMap = {}, playStat = 0, icon;
- let selectVice = GM_getValue('ttsVice', '自动选择');
- let rate = GM_getValue('ttsrate', 1);
- const setIcon = (i) => {
- if (!icon) {
- return
- }
- const pp = icon.parentElement.querySelector('button.pp');
- pp && (pp.innerHTML = i);
- }
- speechSynthesis.addEventListener("voiceschanged", () => {
- if (vices.length < 1) {
- vices = speechSynthesis.getVoices();
- utterance = new SpeechSynthesisUtterance();
- utterance.addEventListener('end', () => {
- playStat = 0;
- setIcon('▶️');
- })
- utterance.addEventListener('pause', (e) => {
- playStat = 2;
- setIcon('▶️');
- })
- utterance.addEventListener('resume', (e) => {
- playStat = 1;
- setIcon('⏸️');
- })
- vices.map(v => viceMap[v.voiceURI] = v);
- }
- });
- function play(text, vice = null) {
- utterance.voice = vice ? vice : viceMap[selectVice];
- utterance.text = text;
- utterance.rate = rate;
- playStat = 1;
- speechSynthesis.speak(utterance);
- }
- function speak(speakText) {
- if (viceMap[selectVice]) {
- play(speakText);
- return
- }
- const la = eld.detect(speakText).language;
- console.log(la);
- for (const value of vices) {
- const lang = value.lang.toLowerCase();
- if (lang.indexOf(la) > -1) {
- vice = value
- break;
- }
- }
- if (!vice) {
- icon.title = '似乎无可用的tts,请先安装';
- return
- }
- play(speakText, vice);
- }
- PushIconAction({
- name: 'tts发音 右键设置语速和语言',
- id: 'icon-speech',
- image: GM_getResourceURL('icon-speak'),
- trigger: function (speakText, _, ev) {
- if (vices.length < 1) {
- ev.target.title = 'tts还没有准备好,请稍等';
- return
- }
- speak(speakText);
- },
- call: (img) => {
- img.addEventListener('contextmenu', (e) => {
- e.preventDefault();
- const content = img.parentElement.querySelector('tr-content');
- content.style.display = 'block';
- const arr = vices.map(v => [`${v.lang} - ${v.localService ? 'local' : ''}-${v.name}`, v.voiceURI]);
- arr.unshift(['自动选择', '']);
- const options = buildOption(arr, selectVice, 1, 0);
- content.querySelector('div').innerHTML = `
- <div class="item">
- <button class="pp">${playStat === 1 ? '⏸️' : '▶️'}</button>
- <button class="stop">⏹️</button>
- </div>
- <div class="item">
- <label for="speakspeed">语速:</label>
- <input id="speakspeed" value="1" min="0" step="0.1" type="number">
- </div>
- <div class="item">
- <label for="language">语言:</label>
- <select id="language">${options}</select>
- </div>
- `;
- icon = content.querySelector('.pp');
- content.querySelector('.stop').addEventListener('click', () => {
- speechSynthesis.cancel();
- playStat = 0;
- icon.innerHTML = '▶️';
- });
- icon.addEventListener('click', function (e) {
- switch (playStat) {
- case 0:
- speak(window.getSelection().toString().trim());
- this.innerHTML = '⏸️';
- break;
- case 1:
- speechSynthesis.pause();
- this.innerHTML = '▶️';
- break;
- case 2:
- speechSynthesis.resume();
- this.innerHTML = '⏸️';
- break;
- default:
- break;
- }
- })
- content.querySelector('#speakspeed').addEventListener('change', function (e) {
- rate = this.value;
- GM_setValue('ttsrate', rate);
- });
- content.querySelector('#language').addEventListener('change', function (e) {
- selectVice = this.value;
- GM_setValue('ttsVice', this.value);
- })
- })
- },
- hide: (icon) => {
- speechSynthesis.cancel();
- setIcon('▶️');
- playStat = 0;
- }
- })
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址