您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动倍速播放并切换到下一个视频(精简版 + 自动恢复播放)
// ==UserScript== // @name 河北省高等学校教师岗前培训课程助手 // @namespace http://your-namespace-here.com/ // @version 0.8 // @description 自动倍速播放并切换到下一个视频(精简版 + 自动恢复播放) // @author 阳阳 // @license MIT // @match http://hbgs.study.gspxonline.com/* // @grant none // ==/UserScript== (function () { 'use strict'; /*** 配置 ***/ let PLAYBACK_SPEED = 5; let NEXT_DELAY = 4000; let CHECK_INTERVAL = 60000; // 自动恢复播放轮询间隔 let currentIndex = 0; let videoList = []; let video = null; let autoPlayTimer = null; /*** 初始化调试面板 ***/ function createDebugPanel() { const panel = document.createElement('div'); panel.id = 'debug-panel'; panel.style.cssText = ` position: fixed; top: 10px; left: 10px; z-index: 99999; background: rgba(0,0,0,0.75); color: #0f0; font-size: 12px; padding: 10px; border-radius: 6px; min-width: 180px; max-width: 250px; font-family: monospace; `; panel.innerHTML = ` <div><b>课程助手调试面板</b></div> <div id="status">状态: 待机中</div> <div style="margin-top:6px;"> 倍速: <input id="speedInput" type="number" value="${PLAYBACK_SPEED}" style="width:50px;" min="1" max="16" /> <button id="setSpeedBtn">设置</button> </div> <div style="margin-top:6px;"> <button id="initBtn">🔧 初始化课程列表</button> <button id="nextBtn">➡️ 下一视频</button> </div> `; document.body.appendChild(panel); document.getElementById('setSpeedBtn').onclick = () => { const val = parseFloat(document.getElementById('speedInput').value); if (!isNaN(val) && val > 0) { PLAYBACK_SPEED = val; if (video) video.playbackRate = PLAYBACK_SPEED; logStatus(`倍速已更新为 ${PLAYBACK_SPEED}x`); } }; document.getElementById('initBtn').onclick = initializeAndSelect; document.getElementById('nextBtn').onclick = handleEnded; } function logStatus(msg) { document.getElementById('status').innerText = "状态: " + msg; } /*** 初始化未完成课程列表 ***/ function initializeVideoList() { videoList = Array.from(document.querySelectorAll('li')).filter(li => { const status = li.querySelector('.learn-status'); return status && !status.classList.contains('finish'); }); logStatus(`找到 ${videoList.length} 个未完成课程`); } /*** 初始化并选择第一条未完成课程 ***/ function initializeAndSelect() { initializeVideoList(); if (videoList.length > 0) { currentIndex = 0; videoList[currentIndex].click(); setTimeout(playVideo, NEXT_DELAY); } else { logStatus('没有未完成课程'); } } /*** 播放视频 ***/ function playVideo() { video = document.querySelector('video'); if (!video) { logStatus('未找到视频,500ms后重试...'); setTimeout(playVideo, 500); return; } video.playbackRate = PLAYBACK_SPEED; video.muted = true; const playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(() => { logStatus(`播放课程 ${currentIndex + 1}/${videoList.length} (x${PLAYBACK_SPEED})`); startAutoPlayWatcher(); }).catch(err => { logStatus('播放失败,可能需要用户交互才能播放'); console.error(err); }); } video.removeEventListener('ended', handleEnded); video.addEventListener('ended', handleEnded); } /*** 自动恢复播放监听 ***/ function startAutoPlayWatcher() { stopAutoPlayWatcher(); autoPlayTimer = setInterval(() => { if (video && video.paused) { video.play(); } }, CHECK_INTERVAL); } function stopAutoPlayWatcher() { if (autoPlayTimer) { clearInterval(autoPlayTimer); autoPlayTimer = null; } } /*** 下一视频 ***/ function handleEnded() { stopAutoPlayWatcher(); currentIndex++; if (currentIndex < videoList.length) { const next = videoList[currentIndex]; logStatus(`切换到下一个课程: ${next.innerText}`); next.click(); setTimeout(playVideo, NEXT_DELAY); } else { logStatus('✅ 所有视频已完成'); } } /*** 初始化面板 ***/ createDebugPanel(); })();