// ==UserScript== // @name 抖音点赞/收藏/推荐/进入下一个视频(陈天翊测试版)带语音播报 // @namespace http://tampermonkey.net/ // @version 1.7 // @description 点赞、收藏、推荐 依据视频刷新量执行 // @author 陈天翊 // @match https://www.douyin.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant unsafeWindow // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // 配置 const CONFIG = { enabled: GM_getValue('enabled', true), // 点赞功能 autoLike: GM_getValue('autoLike', true), likeVideoMin: GM_getValue('likeVideoMin', 5), // 检测到3个新视频 likeVideoMax: GM_getValue('likeVideoMax', 12), // 检测到5个新视频 // 收藏功能 autoCollect: GM_getValue('autoCollect', true), collectVideoMin: GM_getValue('collectVideoMin', 20), // 检测到5个新视频 collectVideoMax: GM_getValue('collectVideoMax', 68), // 检测到8个新视频 // 推荐功能 autoShare: GM_getValue('autoShare', true), shareVideoMin: GM_getValue('shareVideoMin', 30), // 检测到2个新视频 shareVideoMax: GM_getValue('shareVideoMax', 100), // 检测到4个新视频 // 语音播报功能 speechEnabled: GM_getValue('speechEnabled', true), speechRate: GM_getValue('speechRate', 1.0), speechVolume: GM_getValue('speechVolume', 1.0), speechVoice: GM_getValue('speechVoice', ''), // 自动滑动功能 autoSwipe: GM_getValue('autoSwipe', false), swipeMinTime: GM_getValue('swipeMinTime', 5), // 最小停留时间(秒) swipeMaxTime: GM_getValue('swipeMaxTime', 15), // 最大停留时间(秒) swipeKey: GM_getValue('swipeKey', 'ArrowDown') // 滑动按键 }; // 统计 const STATS = { likes: GM_getValue('likes', 0), collects: GM_getValue('collects', 0), shares: GM_getValue('shares', 0), successes: GM_getValue('successes', 0), failures: GM_getValue('failures', 0), videoCount: GM_getValue('videoCount', 0), // 累计新视频数量 swipes: GM_getValue('swipes', 0) // 累计滑动次数 }; // 当前状态 let currentState = { isProcessing: false, currentVideo: '', panelVisible: false, panel: null, panelMinimized: false, // 新增:面板是否最小化 likeCounter: 0, // 点赞计数器 collectCounter: 0, // 收藏计数器 shareCounter: 0, // 推荐计数器 speech: null, // 语音合成对象 voices: [], // 可用语音列表 voiceLoaded: false, // 语音是否已加载 swipeTimer: null, // 滑动计时器 swipeStartTime: 0, // 当前视频开始时间 currentStayTime: 0, // 当前视频计划停留时间 isVideoPlaying: false, // 视频是否在播放 lastSwipeTime: 0 // 上次滑动时间 }; class DouyinAutoHelper { constructor() { this.init(); } init() { console.log('👽 抖音点赞/收藏/推荐 v1.7 已加载(陈天翊测试版)'); this.setupMenuCommands(); this.addCSSStyles(); this.initSpeechSynthesis(); // 等待页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => this.delayedInit()); } else { this.delayedInit(); } } delayedInit() { setTimeout(() => { this.startVideoMonitoring(); if (CONFIG.enabled) { this.startAutoMode(); } // 默认显示控制面板 this.showControlPanel(); console.log('🚀 脚本初始化完成'); console.log('📊 当前执行规则:'); console.log('- 点赞:每' + CONFIG.likeVideoMin + '-' + CONFIG.likeVideoMax + '个新视频'); console.log('- 收藏:每' + CONFIG.collectVideoMin + '-' + CONFIG.collectVideoMax + '个新视频'); console.log('- 推荐:每' + CONFIG.shareVideoMin + '-' + CONFIG.shareVideoMax + '个新视频'); console.log('- 自动滑动:' + (CONFIG.autoSwipe ? '已开启' : '已关闭')); console.log('- 滑动时间:' + CONFIG.swipeMinTime + '-' + CONFIG.swipeMaxTime + '秒'); // 语音播报初始化完成 if (CONFIG.speechEnabled && currentState.voiceLoaded) { this.speak('抖音助手已启动,开始为您服务。'); } // 启动自动滑动 this.updateAutoSwipe(); }, 3000); } // ==================== 自动滑动功能 ==================== getRandomTime() { return Math.floor(Math.random() * (CONFIG.swipeMaxTime - CONFIG.swipeMinTime + 1)) + CONFIG.swipeMinTime; } startAutoSwipe() { if (!CONFIG.autoSwipe || !CONFIG.enabled) { console.log('⏸️ 自动滑动已禁用'); return; } // 清除现有计时器 if (currentState.swipeTimer) { clearTimeout(currentState.swipeTimer); currentState.swipeTimer = null; } // 计算随机停留时间 currentState.currentStayTime = this.getRandomTime(); currentState.swipeStartTime = Date.now(); currentState.lastSwipeTime = 0; // 设置滑动倒计时 this.setSwipeTimer(); // 开始监控视频播放状态 this.startVideoPlaybackMonitoring(); console.log('🔀 自动滑动已启动'); console.log('⏱️ 当前视频停留时间:' + currentState.currentStayTime + '秒'); if (CONFIG.speechEnabled) { this.speak('自动滑动已启动,当前视频停留' + currentState.currentStayTime + '秒'); } } stopAutoSwipe() { if (currentState.swipeTimer) { clearTimeout(currentState.swipeTimer); currentState.swipeTimer = null; } // 停止视频播放监控 this.stopVideoPlaybackMonitoring(); console.log('⏸️ 自动滑动已停止'); if (CONFIG.speechEnabled) { this.speak('自动滑动已停止'); } } toggleAutoSwipe() { CONFIG.autoSwipe = !CONFIG.autoSwipe; GM_setValue('autoSwipe', CONFIG.autoSwipe); if (CONFIG.autoSwipe) { this.startAutoSwipe(); this.showNotification('🔀 自动滑动已开启'); } else { this.stopAutoSwipe(); this.showNotification('⏸️ 自动滑动已关闭'); } this.updateControlPanel(); } setSwipeTimer() { if (!CONFIG.autoSwipe || !CONFIG.enabled) { return; } const now = Date.now(); const elapsed = (now - currentState.swipeStartTime) / 1000; const remaining = Math.max(0, currentState.currentStayTime - elapsed); console.log('⏱️ 滑动倒计时:已停留' + elapsed.toFixed(1) + '秒,剩余' + remaining.toFixed(1) + '秒'); // 更新面板显示 this.updateSwipeTimerDisplay(remaining); if (remaining <= 0) { this.performSwipe(); } else { // 设置下次检查 currentState.swipeTimer = setTimeout(() => { this.setSwipeTimer(); }, 1000); } } performSwipe() { if (!CONFIG.enabled || !CONFIG.autoSwipe) { return; } // 检查是否在冷却期(防止连续滑动) const now = Date.now(); if (now - currentState.lastSwipeTime < 1000) { console.log('⏸️ 滑动冷却中,等待1秒'); setTimeout(() => this.performSwipe(), 1000); return; } console.log('🔀 执行滑动操作,按键:' + CONFIG.swipeKey); // 模拟按键 this.simulateKeyPress(CONFIG.swipeKey); // 更新统计 STATS.swipes++; GM_setValue('swipes', STATS.swipes); // 记录滑动时间 currentState.lastSwipeTime = now; // 语音播报 if (CONFIG.speechEnabled) { this.speak('切换到下一个视频'); } // 重置计时器 this.resetSwipeTimer(); this.showNotification('🔀 切换到下一个视频'); } resetSwipeTimer() { // 重新计算停留时间 currentState.currentStayTime = this.getRandomTime(); currentState.swipeStartTime = Date.now(); console.log('🔄 重置滑动计时器,新停留时间:' + currentState.currentStayTime + '秒'); // 重新设置计时器 if (currentState.swipeTimer) { clearTimeout(currentState.swipeTimer); } this.setSwipeTimer(); } updateAutoSwipe() { if (CONFIG.autoSwipe && CONFIG.enabled) { this.startAutoSwipe(); } else { this.stopAutoSwipe(); } } setSwipeTime(min, max) { CONFIG.swipeMinTime = Math.max(1, min); CONFIG.swipeMaxTime = Math.max(min, max); GM_setValue('swipeMinTime', CONFIG.swipeMinTime); GM_setValue('swipeMaxTime', CONFIG.swipeMaxTime); console.log('⏱️ 滑动时间设置为:' + min + '-' + max + '秒'); if (CONFIG.speechEnabled) { this.speak('滑动时间设置为' + min + '到' + max + '秒'); } // 重置计时器 this.resetSwipeTimer(); } setSwipeKey(key) { CONFIG.swipeKey = key; GM_setValue('swipeKey', key); console.log('⌨️ 滑动按键设置为:' + key); if (CONFIG.speechEnabled) { this.speak('滑动按键已设置为' + key); } } // 监控视频播放状态 startVideoPlaybackMonitoring() { const video = this.getVideoElement(); if (!video) { console.log('⚠️ 未找到视频元素,延迟重试'); setTimeout(() => this.startVideoPlaybackMonitoring(), 1000); return; } // 监听视频播放事件 const handlePlay = () => { currentState.isVideoPlaying = true; console.log('▶️ 视频开始播放'); }; const handlePause = () => { currentState.isVideoPlaying = false; console.log('⏸️ 视频已暂停'); // 视频暂停时暂停计时器 if (currentState.swipeTimer) { clearTimeout(currentState.swipeTimer); console.log('⏸️ 滑动计时器已暂停'); } }; video.addEventListener('play', handlePlay); video.addEventListener('pause', handlePause); // 保存事件监听器以便移除 currentState.videoPlayListener = handlePlay; currentState.videoPauseListener = handlePause; // 检查初始状态 currentState.isVideoPlaying = !video.paused; } stopVideoPlaybackMonitoring() { const video = this.getVideoElement(); if (video && currentState.videoPlayListener && currentState.videoPauseListener) { video.removeEventListener('play', currentState.videoPlayListener); video.removeEventListener('pause', currentState.videoPauseListener); } } // 手动滑动功能 manualSwipe() { this.simulateKeyPress('ArrowDown'); STATS.swipes++; GM_setValue('swipes', STATS.swipes); this.showNotification('🔀 手动切换到下一个视频'); this.updatePanelStats(); if (CONFIG.speechEnabled) { this.speak('已切换到下一个视频'); } // 如果自动滑动开启,重置计时器 if (CONFIG.autoSwipe) { this.resetSwipeTimer(); } } // ==================== 语音播报功能 ==================== initSpeechSynthesis() { if ('speechSynthesis' in window) { currentState.speech = window.speechSynthesis; // 获取可用语音列表 this.loadVoices(); // 监听语音列表加载完成 currentState.speech.onvoiceschanged = () => { this.loadVoices(); }; console.log('🎤 语音播报功能已初始化'); } else { console.warn('⚠️ 浏览器不支持语音合成功能'); } } loadVoices() { if (!currentState.speech) return; const voices = currentState.speech.getVoices(); if (voices.length > 0) { currentState.voices = voices; currentState.voiceLoaded = true; console.log('🎤 可用语音列表加载完成,共' + voices.length + '个语音'); // 尝试设置首选中文语音 if (!CONFIG.speechVoice) { const chineseVoice = voices.find(voice => voice.lang.startsWith('zh-') || voice.name.toLowerCase().includes('chinese') ); if (chineseVoice) { CONFIG.speechVoice = chineseVoice.name; console.log('🎤 自动选择中文语音:' + chineseVoice.name); } } } } speak(text, rate = CONFIG.speechRate, volume = CONFIG.speechVolume) { if (!CONFIG.speechEnabled || !currentState.speech || !currentState.voiceLoaded) { console.log('🎤 语音播报已禁用或不可用'); return; } // 停止当前正在播放的语音 if (currentState.speech.speaking) { currentState.speech.cancel(); } const utterance = new SpeechSynthesisUtterance(text); utterance.rate = rate; utterance.volume = volume; // 设置语音 if (CONFIG.speechVoice) { const selectedVoice = currentState.voices.find(voice => voice.name === CONFIG.speechVoice); if (selectedVoice) { utterance.voice = selectedVoice; } } // 语音播放事件 utterance.onstart = () => { console.log('🎤 开始播报:' + text); }; utterance.onend = () => { console.log('🎤 播报结束'); }; utterance.onerror = (event) => { console.error('🎤 语音播报错误:', event); }; // 播放语音 currentState.speech.speak(utterance); } toggleSpeech() { CONFIG.speechEnabled = !CONFIG.speechEnabled; GM_setValue('speechEnabled', CONFIG.speechEnabled); if (CONFIG.speechEnabled) { this.speak('语音播报已开启'); this.showNotification('🎤 语音播报已开启'); } else { this.speak('语音播报已关闭'); this.showNotification('🔇 语音播报已关闭'); } this.updateControlPanel(); } setSpeechRate(rate) { CONFIG.speechRate = rate; GM_setValue('speechRate', rate); this.speak('语音速度已设置为' + rate.toFixed(1)); } setSpeechVolume(volume) { CONFIG.speechVolume = volume; GM_setValue('speechVolume', volume); this.speak('语音音量已设置为' + (volume * 100) + '百分比'); } setSpeechVoice(voiceName) { CONFIG.speechVoice = voiceName; GM_setValue('speechVoice', voiceName); this.speak('语音已切换为' + voiceName); } showVoiceSelector() { if (!currentState.voices.length) { alert('无法获取语音列表,请刷新页面后重试'); return; } let voiceList = '请选择语音:\n\n'; currentState.voices.forEach((voice, index) => { const isSelected = voice.name === CONFIG.speechVoice ? '✅ ' : ' '; voiceList += `${index + 1}. ${isSelected}${voice.name} (${voice.lang})\n`; }); const choice = prompt(voiceList + '\n请输入要选择的语音编号:'); if (choice && !isNaN(choice)) { const index = parseInt(choice) - 1; if (index >= 0 && index < currentState.voices.length) { this.setSpeechVoice(currentState.voices[index].name); } } } // ==================== 菜单命令 ==================== setupMenuCommands() { if (typeof GM_registerMenuCommand === 'function') { GM_registerMenuCommand('🎮 显示控制面板', () => this.showControlPanel()); GM_registerMenuCommand('📊 查看统计', () => this.showStats()); GM_registerMenuCommand('▶️ 启动自动模式', () => this.startAutoMode()); GM_registerMenuCommand('⏸️ 停止自动模式', () => this.stopAutoMode()); GM_registerMenuCommand('🔀 开启/关闭自动滑动', () => this.toggleAutoSwipe()); GM_registerMenuCommand('🎤 开启/关闭语音播报', () => this.toggleSpeech()); GM_registerMenuCommand('🧹 重置统计', () => this.resetStats()); } } addCSSStyles() { const style = document.createElement('style'); style.textContent = ` .tianyi-panel { position: fixed; top: 20px; left: 20px; background: linear-gradient(135deg, #0f0c29, #302b63, #24243e); color: white; padding: 15px; border-radius: 10px; z-index: 10000; font-family: system-ui; font-size: 12px; min-width: 320px; box-shadow: 0 5px 20px rgba(0,0,0,0.3); border: 2px solid #4cc9f0; transition: all 0.3s ease; } .tianyi-panel-minimized { padding: 5px 15px; min-width: 150px; } .tianyi-panel-hidden { display: none; } .tianyi-panel-content { transition: all 0.3s ease; } .tianyi-panel-minimized .tianyi-panel-content { display: none; } .tianyi-notification { position: fixed; bottom: 20px; right: 20px; background: #0f0c29; color: white; padding: 10px 15px; border-radius: 5px; z-index: 10001; font-size: 14px; border-left: 4px solid #4cc9f0; animation: tianyiSlideIn 0.3s ease-out; } @keyframes tianyiSlideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .tianyi-btn { padding: 8px 12px; border: none; border-radius: 5px; color: white; cursor: pointer; margin: 2px; font-size: 11px; transition: all 0.3s; } .tianyi-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.3); } .tianyi-counter { font-size: 9px; opacity: 0.7; margin-top: 2px; } .tianyi-panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .tianyi-minimize-btn { background: transparent; border: none; color: white; font-size: 16px; cursor: pointer; padding: 2px 8px; border-radius: 3px; transition: all 0.3s; } .tianyi-minimize-btn:hover { background: rgba(255,255,255,0.1); } .tianyi-minimized-content { display: flex; align-items: center; justify-content: space-between; width: 100%; } .tianyi-minimized-stats { display: flex; gap: 10px; } .tianyi-minimized-stat { font-size: 11px; text-align: center; } .tianyi-minimized-icon { font-size: 12px; margin-right: 2px; } .tianyi-minimized-count { font-weight: bold; font-size: 13px; } .tianyi-speech-controls { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-top: 5px; } .tianyi-speech-btn { padding: 4px 8px; font-size: 10px; } .tianyi-speech-status { display: flex; align-items: center; justify-content: space-between; background: rgba(255,255,255,0.1); padding: 4px 8px; border-radius: 3px; margin-bottom: 5px; } .tianyi-speech-indicator { width: 8px; height: 8px; border-radius: 50%; background-color: ${CONFIG.speechEnabled ? '#4cc9f0' : '#888'}; animation: ${CONFIG.speechEnabled ? 'tianyiPulse 2s infinite' : 'none'}; } @keyframes tianyiPulse { 0% { opacity: 1; } 50% { opacity: 0.3; } 100% { opacity: 1; } } .tianyi-slider-container { display: flex; align-items: center; gap: 8px; font-size: 10px; } .tianyi-slider { flex: 1; height: 4px; background: rgba(255,255,255,0.2); border-radius: 2px; outline: none; -webkit-appearance: none; } .tianyi-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; border-radius: 50%; background: #4cc9f0; cursor: pointer; } .tianyi-voice-btn { width: 100%; margin-top: 5px; } .tianyi-swipe-timer { font-size: 10px; text-align: center; background: rgba(255,255,255,0.1); padding: 4px 8px; border-radius: 3px; margin-top: 5px; font-family: monospace; } .tianyi-swipe-remaining { color: #4cc9f0; font-weight: bold; font-size: 12px; } .tianyi-swipe-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-top: 5px; } .tianyi-swipe-settings { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 5px; } .tianyi-swipe-input { background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: white; padding: 4px 8px; border-radius: 3px; font-size: 10px; width: 100%; } .tianyi-swipe-input:focus { outline: none; border-color: #4cc9f0; } .tianyi-swipe-label { font-size: 9px; opacity: 0.8; margin-top: 2px; } .tianyi-status-indicator { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; } .tianyi-status-active { background-color: #4cc9f0; animation: tianyiPulse 1s infinite; } .tianyi-status-inactive { background-color: #888; } .tianyi-status-playing { background-color: #f72585; } `; document.head.appendChild(style); } // ==================== 核心功能 ==================== getRandomCount(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } performLike() { console.log('执行点赞操作'); this.simulateKeyPress('z'); STATS.likes++; this.saveStats(); this.updatePanelStats(); // 重置计数器 currentState.likeCounter = 0; this.showNotification('❤️ 点赞成功'); // 语音播报 if (CONFIG.speechEnabled) { this.speak('点赞成功'); } STATS.successes++; this.saveStats(); } performCollect() { console.log('执行收藏操作'); this.simulateKeyPress('c'); STATS.collects++; this.saveStats(); this.updatePanelStats(); // 重置计数器 currentState.collectCounter = 0; this.showNotification('⭐ 收藏成功'); // 语音播报 if (CONFIG.speechEnabled) { this.speak('收藏成功'); } STATS.successes++; this.saveStats(); } performShare() { console.log('执行推荐操作'); this.simulateKeyPress('p'); STATS.shares++; this.saveStats(); this.updatePanelStats(); // 等待推荐面板打开后关闭 setTimeout(() => { this.simulateKeyPress('Escape'); }, 1000); // 重置计数器 currentState.shareCounter = 0; this.showNotification('📤 推荐成功'); // 语音播报 if (CONFIG.speechEnabled) { this.speak('推荐成功'); } STATS.successes++; this.saveStats(); } // ==================== 自动模式 ==================== startAutoMode() { CONFIG.enabled = true; GM_setValue('enabled', true); console.log('启动自动模式'); this.showNotification('👽 自动模式已启动'); // 语音播报 if (CONFIG.speechEnabled) { this.speak('自动模式已启动,开始为您服务'); } // 更新自动滑动 this.updateAutoSwipe(); this.updateControlPanel(); } stopAutoMode() { CONFIG.enabled = false; GM_setValue('enabled', false); console.log('停止自动模式'); this.showNotification('⏸️ 自动模式已停止'); // 语音播报 if (CONFIG.speechEnabled) { this.speak('自动模式已停止'); } // 停止自动滑动 this.stopAutoSwipe(); this.updateControlPanel(); } toggleAutoMode() { if (CONFIG.enabled) { this.stopAutoMode(); } else { this.startAutoMode(); } } // 检测新视频 startVideoMonitoring() { let lastVideoSrc = ''; setInterval(() => { if (!CONFIG.enabled) return; const video = this.getVideoElement(); if (video && video.src && video.src !== lastVideoSrc) { console.log('🎬 检测到新视频'); lastVideoSrc = video.src; // 增加视频计数 STATS.videoCount++; this.saveStats(); // 增加各功能计数器 currentState.likeCounter++; currentState.collectCounter++; currentState.shareCounter++; // 更新面板显示 this.updatePanelStats(); // 重置滑动计时器 if (CONFIG.autoSwipe) { this.resetSwipeTimer(); } // 检查是否满足执行条件 this.checkAndExecuteActions(); } }, 2000); } checkAndExecuteActions() { console.log('📊 计数器状态:'); console.log('- 点赞计数器:' + currentState.likeCounter + '/' + CONFIG.likeVideoMin + '-' + CONFIG.likeVideoMax); console.log('- 收藏计数器:' + currentState.collectCounter + '/' + CONFIG.collectVideoMin + '-' + CONFIG.collectVideoMax); console.log('- 推荐计数器:' + currentState.shareCounter + '/' + CONFIG.shareVideoMin + '-' + CONFIG.shareVideoMax); // 检查点赞条件 if (CONFIG.autoLike && currentState.likeCounter >= this.getRandomCount(CONFIG.likeVideoMin, CONFIG.likeVideoMax)) { console.log('✅ 满足点赞条件,执行点赞'); this.performLike(); } // 检查收藏条件 if (CONFIG.autoCollect && currentState.collectCounter >= this.getRandomCount(CONFIG.collectVideoMin, CONFIG.collectVideoMax)) { console.log('✅ 满足收藏条件,执行收藏'); this.performCollect(); } // 检查推荐条件 if (CONFIG.autoShare && currentState.shareCounter >= this.getRandomCount(CONFIG.shareVideoMin, CONFIG.shareVideoMax)) { console.log('✅ 满足推荐条件,执行推荐'); this.performShare(); } } // ==================== 控制面板 ==================== showControlPanel() { if (currentState.panel) { currentState.panel.classList.remove('tianyi-panel-hidden'); currentState.panelVisible = true; this.updateControlPanel(); return; } const panel = document.createElement('div'); panel.className = 'tianyi-panel'; panel.innerHTML = this.getPanelHTML(); document.body.appendChild(panel); this.setupPanelEvents(panel); this.makeDraggable(panel); currentState.panel = panel; currentState.panelVisible = true; } getPanelHTML() { if (currentState.panelMinimized) { return this.getMinimizedPanelHTML(); } return this.getFullPanelHTML(); } getFullPanelHTML() { const remaining = Math.max(0, currentState.currentStayTime - ((Date.now() - currentState.swipeStartTime) / 1000)); return `
陈天翊抖音助手(测试版)
点赞
${STATS.likes}
${currentState.likeCounter}/${CONFIG.likeVideoMin}-${CONFIG.likeVideoMax}
收藏
${STATS.collects}
${currentState.collectCounter}/${CONFIG.collectVideoMin}-${CONFIG.collectVideoMax}
推荐
${STATS.shares}
${currentState.shareCounter}/${CONFIG.shareVideoMin}-${CONFIG.shareVideoMax}
滑动
${STATS.swipes}
自动: ${CONFIG.autoSwipe ? '开' : '关'}
累计视频: ${STATS.videoCount}
成功率: ${STATS.successes + STATS.failures > 0 ? Math.round((STATS.successes / (STATS.successes + STATS.failures)) * 100) : 0}%
自动滑动
每 ${CONFIG.swipeMinTime}-${CONFIG.swipeMaxTime} 秒
剩余时间: ${remaining.toFixed(1)}
滑动设置
最小时间(秒)
最大时间(秒)
语音播报
${CONFIG.speechEnabled ? '🎤 已开启' : '🔇 已关闭'}
语速: ${CONFIG.speechRate.toFixed(1)}x
音量: ${Math.round(CONFIG.speechVolume * 100)}%
执行规则
每N个新视频执行
❤️ 点赞 每 ${CONFIG.likeVideoMin}-${CONFIG.likeVideoMax} 个视频
⭐ 收藏 每 ${CONFIG.collectVideoMin}-${CONFIG.collectVideoMax} 个视频
📤 推荐 每 ${CONFIG.shareVideoMin}-${CONFIG.shareVideoMax} 个视频
手动操作
温馨提示此脚本仅限于测试操作如果用于非法操作与作者无关
作者:陈天翊
功能:滑动/点赞/收藏/推荐
可自定义滑动随机时间间隔
`; } getMinimizedPanelHTML() { const remaining = Math.max(0, currentState.currentStayTime - ((Date.now() - currentState.swipeStartTime) / 1000)); return `
❤️
${STATS.likes}
${STATS.collects}
📤
${STATS.shares}
⬇️
${STATS.swipes}
`; } setupPanelEvents(panel) { if (currentState.panelMinimized) { panel.querySelector('#tianyi-expand').addEventListener('click', () => this.toggleMinimize()); panel.querySelector('#tianyi-close').addEventListener('click', () => this.hideControlPanel()); } else { // 主功能按钮 panel.querySelector('#tianyi-toggle').addEventListener('click', () => this.toggleAutoMode()); panel.querySelector('#tianyi-like').addEventListener('click', () => this.performLike()); panel.querySelector('#tianyi-collect').addEventListener('click', () => this.performCollect()); panel.querySelector('#tianyi-share').addEventListener('click', () => this.performShare()); panel.querySelector('#tianyi-minimize').addEventListener('click', () => this.toggleMinimize()); panel.querySelector('#tianyi-close').addEventListener('click', () => this.hideControlPanel()); // 滑动控制按钮 panel.querySelector('#tianyi-toggle-swipe').addEventListener('click', () => this.toggleAutoSwipe()); panel.querySelector('#tianyi-manual-swipe').addEventListener('click', () => this.manualSwipe()); panel.querySelector('#tianyi-save-swipe').addEventListener('click', () => { const min = parseInt(panel.querySelector('#tianyi-swipe-min').value); const max = parseInt(panel.querySelector('#tianyi-swipe-max').value); this.setSwipeTime(min, max); }); // 语音控制按钮 panel.querySelector('#tianyi-toggle-speech').addEventListener('click', () => this.toggleSpeech()); panel.querySelector('#tianyi-voice-select').addEventListener('click', () => this.showVoiceSelector()); panel.querySelector('#tianyi-test-speech').addEventListener('click', () => this.speak('测试语音播报功能,当前语音速度' + CONFIG.speechRate.toFixed(1) + '倍,音量' + (CONFIG.speechVolume * 100) + '百分比')); panel.querySelector('#tianyi-stop-speech').addEventListener('click', () => { if (currentState.speech && currentState.speech.speaking) { currentState.speech.cancel(); this.showNotification('🔇 语音已停止'); } }); panel.querySelector('#tianyi-speech-stats').addEventListener('click', () => this.speakStats()); // 语音设置滑块 const rateSlider = panel.querySelector('#tianyi-speech-rate'); const volumeSlider = panel.querySelector('#tianyi-speech-volume'); rateSlider.addEventListener('input', (e) => { const rate = parseFloat(e.target.value); this.setSpeechRate(rate); panel.querySelector('.tianyi-slider-container:nth-child(3) span:last-child').textContent = rate.toFixed(1) + 'x'; }); volumeSlider.addEventListener('input', (e) => { const volume = parseFloat(e.target.value); this.setSpeechVolume(volume); panel.querySelector('.tianyi-slider-container:nth-child(4) span:last-child').textContent = Math.round(volume * 100) + '%'; }); // 双击标题切换自动模式 const title = panel.querySelector('.tianyi-panel-header strong'); title.addEventListener('dblclick', () => this.toggleAutoMode()); } } updateSwipeTimerDisplay(remaining) { if (!currentState.panel || currentState.panelMinimized) return; const timerEl = currentState.panel.querySelector('#tianyi-swipe-timer'); const remainingEl = currentState.panel.querySelector('.tianyi-swipe-remaining'); if (timerEl && remainingEl) { if (CONFIG.autoSwipe && CONFIG.enabled) { timerEl.style.display = 'block'; remainingEl.textContent = remaining.toFixed(1); } else { timerEl.style.display = 'none'; } } } toggleMinimize() { currentState.panelMinimized = !currentState.panelMinimized; if (currentState.panel) { if (currentState.panelMinimized) { currentState.panel.classList.add('tianyi-panel-minimized'); } else { currentState.panel.classList.remove('tianyi-panel-minimized'); } // 重新渲染面板 currentState.panel.innerHTML = this.getPanelHTML(); this.setupPanelEvents(currentState.panel); this.updatePanelStats(); } this.showNotification(currentState.panelMinimized ? '📱 面板已最小化' : '📱 面板已展开'); } updateControlPanel() { if (!currentState.panel) return; if (!currentState.panelMinimized) { const toggleBtn = currentState.panel.querySelector('#tianyi-toggle'); const toggleSwipeBtn = currentState.panel.querySelector('#tianyi-toggle-swipe'); const toggleSpeechBtn = currentState.panel.querySelector('#tianyi-toggle-speech'); const speechIndicator = currentState.panel.querySelectorAll('.tianyi-status-indicator'); if (toggleBtn) { toggleBtn.textContent = CONFIG.enabled ? '⏸️ 停止自动' : '▶️ 启动自动'; toggleBtn.style.background = CONFIG.enabled ? '#f72585' : '#4cc9f0'; } if (toggleSwipeBtn) { toggleSwipeBtn.textContent = CONFIG.autoSwipe ? '⏸️ 关闭滑动' : '🔀 开启滑动'; } if (toggleSpeechBtn) { toggleSpeechBtn.textContent = CONFIG.speechEnabled ? '🔇 关闭语音' : '🎤 开启语音'; } // 更新状态指示器 if (speechIndicator.length >= 2) { speechIndicator[0].className = `tianyi-status-indicator ${CONFIG.autoSwipe ? 'tianyi-status-active' : 'tianyi-status-inactive'}`; speechIndicator[1].className = `tianyi-status-indicator ${CONFIG.speechEnabled ? 'tianyi-status-active' : 'tianyi-status-inactive'}`; } } } updatePanelStats() { if (!currentState.panel) return; if (currentState.panelMinimized) { const likesEl = currentState.panel.querySelector('#tianyi-stat-likes-mini'); const collectsEl = currentState.panel.querySelector('#tianyi-stat-collects-mini'); const sharesEl = currentState.panel.querySelector('#tianyi-stat-shares-mini'); const swipesEl = currentState.panel.querySelector('#tianyi-stat-swipes-mini'); if (likesEl) likesEl.textContent = STATS.likes; if (collectsEl) collectsEl.textContent = STATS.collects; if (sharesEl) sharesEl.textContent = STATS.shares; if (swipesEl) swipesEl.textContent = STATS.swipes; } else { const likesEl = currentState.panel.querySelector('#tianyi-stat-likes'); const collectsEl = currentState.panel.querySelector('#tianyi-stat-collects'); const sharesEl = currentState.panel.querySelector('#tianyi-stat-shares'); const swipesEl = currentState.panel.querySelector('#tianyi-stat-swipes'); const videosEl = currentState.panel.querySelector('#tianyi-stat-videos'); const likeCounterEl = currentState.panel.querySelector('#tianyi-counter-like'); const collectCounterEl = currentState.panel.querySelector('#tianyi-counter-collect'); const shareCounterEl = currentState.panel.querySelector('#tianyi-counter-share'); const successRateEl = currentState.panel.querySelector('#tianyi-success-rate'); if (likesEl) likesEl.textContent = STATS.likes; if (collectsEl) collectsEl.textContent = STATS.collects; if (sharesEl) sharesEl.textContent = STATS.shares; if (swipesEl) swipesEl.textContent = STATS.swipes; if (videosEl) videosEl.textContent = STATS.videoCount; if (likeCounterEl) likeCounterEl.textContent = `${currentState.likeCounter}/${CONFIG.likeVideoMin}-${CONFIG.likeVideoMax}`; if (collectCounterEl) collectCounterEl.textContent = `${currentState.collectCounter}/${CONFIG.collectVideoMin}-${CONFIG.collectVideoMax}`; if (shareCounterEl) shareCounterEl.textContent = `${currentState.shareCounter}/${CONFIG.shareVideoMin}-${CONFIG.shareVideoMax}`; if (successRateEl) { const total = STATS.successes + STATS.failures; const rate = total > 0 ? Math.round((STATS.successes / total) * 100) : 0; successRateEl.textContent = `${rate}%`; } } } speakStats() { if (!CONFIG.speechEnabled) { this.showNotification('🔇 请先开启语音播报功能'); return; } const successRate = STATS.successes + STATS.failures > 0 ? Math.round((STATS.successes / (STATS.successes + STATS.failures)) * 100) : 0; const statsText = ` 当前统计信息:点赞 ${STATS.likes} 次,收藏 ${STATS.collects} 次,推荐 ${STATS.shares} 次, 累计观看 ${STATS.videoCount} 个视频,自动滑动 ${STATS.swipes} 次,成功率为 ${successRate} 百分比。 点赞计数器:${currentState.likeCounter},收藏计数器:${currentState.collectCounter},推荐计数器:${currentState.shareCounter}。 `.replace(/\s+/g, ' ').trim(); this.speak(statsText); } hideControlPanel() { if (currentState.panel) { currentState.panel.classList.add('tianyi-panel-hidden'); currentState.panelVisible = false; } } toggleControlPanel() { if (currentState.panelVisible) { this.hideControlPanel(); } else { this.showControlPanel(); } } makeDraggable(element) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; const header = element.querySelector('.tianyi-panel-header') || element; header.style.cursor = 'move'; header.addEventListener('mousedown', dragMouseDown); function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; } } // ==================== 工具方法 ==================== getVideoElement() { return document.querySelector('video'); } simulateKeyPress(key) { const event = new KeyboardEvent('keydown', { key: key, code: key === 'ArrowDown' ? 'ArrowDown' : `Key${key.toUpperCase()}`, keyCode: key === 'ArrowDown' ? 40 : key.toUpperCase().charCodeAt(0), which: key === 'ArrowDown' ? 40 : key.toUpperCase().charCodeAt(0), bubbles: true, cancelable: true }); document.dispatchEvent(event); } saveStats() { GM_setValue('likes', STATS.likes); GM_setValue('collects', STATS.collects); GM_setValue('shares', STATS.shares); GM_setValue('successes', STATS.successes); GM_setValue('failures', STATS.failures); GM_setValue('videoCount', STATS.videoCount); GM_setValue('swipes', STATS.swipes); } showNotification(text, duration = 2000) { const notification = document.createElement('div'); notification.className = 'tianyi-notification'; notification.textContent = text; document.body.appendChild(notification); setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, duration); } showStats() { const statsText = ` 🚀 抖音助手统计 =============== 点赞次数: ${STATS.likes} 收藏次数: ${STATS.collects} 推荐次数: ${STATS.shares} 累计视频: ${STATS.videoCount} 滑动次数: ${STATS.swipes} 成功次数: ${STATS.successes} 失败次数: ${STATS.failures} 成功率: ${STATS.successes + STATS.failures > 0 ? Math.round((STATS.successes / (STATS.successes + STATS.failures)) * 100) : 0}% =============== 执行规则: 点赞: 每 ${CONFIG.likeVideoMin}-${CONFIG.likeVideoMax} 个新视频 收藏: 每 ${CONFIG.collectVideoMin}-${CONFIG.collectVideoMax} 个新视频 推荐: 每 ${CONFIG.shareVideoMin}-${CONFIG.shareVideoMax} 个新视频 滑动: 每 ${CONFIG.swipeMinTime}-${CONFIG.swipeMaxTime} 秒 =============== 计数器状态: 点赞: ${currentState.likeCounter}/${CONFIG.likeVideoMin}-${CONFIG.likeVideoMax} 收藏: ${currentState.collectCounter}/${CONFIG.collectVideoMin}-${CONFIG.collectVideoMax} 推荐: ${currentState.shareCounter}/${CONFIG.shareVideoMin}-${CONFIG.shareVideoMax} 滑动剩余: ${Math.max(0, currentState.currentStayTime - ((Date.now() - currentState.swipeStartTime) / 1000)).toFixed(1)}秒 `; alert(statsText); } resetStats() { if (confirm('确定要重置所有统计和计数器吗?')) { STATS.likes = 0; STATS.collects = 0; STATS.shares = 0; STATS.videoCount = 0; STATS.swipes = 0; STATS.successes = 0; STATS.failures = 0; currentState.likeCounter = 0; currentState.collectCounter = 0; currentState.shareCounter = 0; this.saveStats(); this.updatePanelStats(); this.showNotification('📊 统计和计数器已重置'); this.speak('统计和计数器已重置'); // 重置滑动计时器 if (CONFIG.autoSwipe) { this.resetSwipeTimer(); } } } } // 初始化脚本 let automation; function init() { if (!automation) { automation = new DouyinAutoHelper(); window.tianyiAutomation = automation; } } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();