您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
使用 Web Audio API 播放提示音,不依赖外链,避免无声,稳定可靠;每次回答后提醒一次。
// ==UserScript== // @name ChatGPT 回答完成提示音(WebAudio 方式) // @namespace https://github.com/xiaozhang // @version 1.6 // @description 使用 Web Audio API 播放提示音,不依赖外链,避免无声,稳定可靠;每次回答后提醒一次。 // @author 小张 // @match https://chatgpt.com/* // @grant none // @run-at document-end // @license MIT // ==/UserScript== (function () { 'use strict'; let lastContentLength = 0; let isAnswering = false; let hasAlerted = false; let lastAnswerId = null; let soundUnlocked = false; let audioCtx = null; let stableCounter = 0; // 新增:稳定不变次数 const STABLE_THRESHOLD = 10; // 100ms × 10 = 1秒未变化才触发提醒 // 解锁音频(需要用户首次点击) window.addEventListener('click', function unlockAudio() { if (!soundUnlocked) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); playBeep(); // 解锁一次 soundUnlocked = true; console.log('🔓 音频权限已解锁'); } window.removeEventListener('click', unlockAudio); }); // 用 Web Audio 播放 Beep function playBeep() { if (!audioCtx) return; const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1000, audioCtx.currentTime); gainNode.gain.setValueAtTime(0.2, audioCtx.currentTime); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.start(); oscillator.stop(audioCtx.currentTime + 0.2); } setInterval(() => { const chatContainer = document.querySelector('main'); if (!chatContainer) return; const chatContents = chatContainer.querySelectorAll('[data-message-author-role="assistant"]'); if (chatContents.length === 0) return; const lastContent = chatContents[chatContents.length - 1]; const currentText = lastContent.innerText.trim(); const currentLength = currentText.length; const currentId = lastContent.getAttribute('data-message-id') || lastContent.innerHTML.slice(0, 50); // 如果是新回答,重置所有状态 if (currentId !== lastAnswerId) { lastAnswerId = currentId; lastContentLength = 0; isAnswering = false; hasAlerted = false; stableCounter = 0; } // 回答还在增长中 if (currentLength > lastContentLength + 5) { isAnswering = true; hasAlerted = false; lastContentLength = currentLength; stableCounter = 0; } // 回答稳定不变 else if (isAnswering && !hasAlerted && currentLength === lastContentLength) { stableCounter++; if (stableCounter >= STABLE_THRESHOLD) { playBeep(); hasAlerted = true; isAnswering = false; } } }, 100); })();