// ==UserScript== // @name 华医网视频自动播放自动切换下一个 // @namespace https://jiaobenmiao.com/ // @version 1.0.1 // @description 华医网视频自动播放下一集 屏蔽弹窗 自动签到 静音播放 悬浮面板 有问题可留言反馈,看到会及时更新 // @author 原作者dennischancs 修改人蓝色魔宙 // @match *://*.91huayi.com/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; let clock = null; let timeCheckInterval = null; let isExpanded = false; const currentSpeed = 1.0; const urlTip = window.location.pathname.split('/').pop().split('?')[0]; // 安全JSON解析 function safeParseJSON(jsonString, defaultValue = null) { try { if (!jsonString || jsonString.trim() === '') return defaultValue; return JSON.parse(jsonString); } catch (e) { console.warn('JSON解析错误:', e); return defaultValue; } } // 元素可见判断 function isElementVisible(element) { if (!element) return false; const style = window.getComputedStyle(element); const rect = element.getBoundingClientRect(); return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0' && rect.width > 0 && rect.height > 0 && element.offsetParent !== null; } // 初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { createFixedPopup(); init(); }); } else { createFixedPopup(); init(); } function init() { createPanel(); if (urlTip.includes('course_ware')) { setPanelStatus('playing'); saveCourseList(); initVideo(0); } else if (urlTip == 'face.aspx') { setPanelStatus('face'); setTimeout(() => location.reload(), 5 * 60 * 1000); } else if (urlTip == 'course.aspx' || urlTip == 'cme.aspx') { setPanelStatus('list'); saveCourseList(); setTimeout(() => location.reload(), 5 * 60 * 1000); } else if (urlTip == 'exam_result.aspx') { setPanelStatus('exam'); initExamPage(); } else { setPanelStatus('error'); } } // 视频初始化(无播放器切换) function initVideo(type) { blockPopups(); simulateUserActivity(); window.onload = () => { clock = setInterval(checkVideoStatus, 3000); }; setTimeout(() => { try { const video = document.querySelector('video'); if (video) { video.muted = true; video.defaultMuted = true; video.playbackRate = 1.0; video.addEventListener('ended', () => { console.log('视频自然结束'); setTimeout(checkVideoStatus, 100); }); } } catch (e) { console.log('播放器初始化错误:', e); } }, 8000); window.addEventListener('beforeunload', () => { clearInterval(clock); clearInterval(timeCheckInterval); }); } // 保存课程列表 function saveCourseList() { const courses = []; const items = document.querySelectorAll('.lis-inside-content, .r .lis, a[onclick*="cwid"]'); items.forEach((item, idx) => { const title = item.querySelector('h2, h3, .title, a')?.textContent.trim(); const status = item.querySelector('button, .status')?.textContent.trim() || '未知'; const onclick = item.getAttribute('onclick') || item.querySelector('[onclick*="cwid"]')?.getAttribute('onclick'); const cwid = onclick?.match(/cwid=([^'"\)]+)/)?.[1]; if (cwid && title) courses.push({ title, status, cwid, index: idx }); }); if (courses.length > 0) { localStorage.setItem('huayi_course_list', JSON.stringify(courses)); console.log(`已保存 ${courses.length} 个课程`); } } // 视频状态检测 function checkVideoStatus() { try { let state = null; const stateEl = document.querySelector("i[id='top_play']"); if (stateEl) { state = stateEl.parentNode?.nextElementSibling?.nextElementSibling?.nextElementSibling?.innerText; } if (!state) { document.querySelectorAll('button, .state').forEach(btn => { const text = btn.textContent; if (text?.includes('已完成') || text?.includes('待考试')) state = text.trim(); }); } const video = document.querySelector('video'); if (video && video.ended) { const isLearning = !state || state.includes('学习中') || state.includes('未学习'); if (isLearning) { console.log('播放完成,5秒后跳转'); setPanelStatus('completed'); clearInterval(clock); setTimeout(() => proceedToNext(), 5000); return; } } if (state == '已完成') { console.log('已完成,准备跳转'); setPanelStatus('completed'); clearInterval(clock); setTimeout(() => proceedToNext(), 2000); } else if (state == '待考试') { console.log('待考试,5秒后跳转'); clearInterval(clock); setTimeout(() => proceedToNext(), 5000); } } catch (e) { console.log('状态检测错误:', e); } } // 跳转到下一课 function proceedToNext() { const courses = safeParseJSON(localStorage.getItem('huayi_course_list'), []); const currentCwid = new URLSearchParams(location.search).get('cwid'); const currentIdx = courses.findIndex(c => c.cwid === currentCwid); const isIncomplete = s => !s || (!s.toLowerCase().includes('已完成') && !s.toLowerCase().includes('完成')); let nextCourse = null; for (let i = currentIdx + 1; i < courses.length; i++) { if (isIncomplete(courses[i].status)) { nextCourse = courses[i]; break; } } if (!nextCourse) { for (let i = 0; i < currentIdx; i++) { if (isIncomplete(courses[i].status)) { nextCourse = courses[i]; break; } } } if (nextCourse) { console.log('跳转到:' + nextCourse.title); setTimeout(() => location.href = `course_ware.aspx?cwid=${nextCourse.cwid}`, 1000); } else { console.log('无下一课,刷新'); setTimeout(() => location.reload(), 2000); } } // 屏蔽弹窗 + 自动签到 function blockPopups() { setInterval(() => { try { if (typeof $ !== 'undefined') { if ($('.pv-ask-head').length) $('.pv-ask-skip').click(); if ($('.signBtn,.btn_sign').length) $('.signBtn,.btn_sign').click(); $("button[onclick='closeBangZhu()']").click(); $('.ccSignWrapBtn:visible').click(); } const video = document.querySelector('video'); const state = document.querySelector("i[id='top_play']")?.parentNode?.nextElementSibling?.nextElementSibling?.nextElementSibling?.innerText; if (video?.paused && state != '已完成' && state != '待考试') { video.play(); video.muted = true; } } catch (e) {} }, 10000); setInterval(() => { try { const ccSign = document.querySelector('.ccSignWrap:visible .ccSignWrapBtn'); if (ccSign) ccSign.click(); document.querySelectorAll('button,a').forEach(btn => { const t = btn.textContent?.trim(); if (t && (t.includes('签到') || t.includes('点击签到')) && isElementVisible(btn)) btn.click(); }); } catch (e) {} }, 2000); } // 模拟用户行为 function simulateUserActivity() { const getVideoArea = () => { const v = document.querySelector('video'); return v ? v.getBoundingClientRect() : { x: innerWidth * 0.2, y: innerHeight * 0.2, width: innerWidth * 0.6, height: innerHeight * 0.6 }; }; const move = () => { const r = getVideoArea(); for (let i = 0; i < 3; i++) { setTimeout(() => { const x = r.x + Math.random() * r.width; const y = r.y + Math.random() * r.height; document.dispatchEvent(new MouseEvent('mousemove', { bubbles: true, clientX: x, clientY: y })); }, i * 200); } }; const schedule = () => { setTimeout(() => { move(); schedule(); }, Math.random() * 300000 + 300000); }; setTimeout(schedule, Math.random() * 60000 + 30000); } // 考试页处理 function initExamPage() { const click = () => { document.querySelectorAll('button,a').forEach(b => { if (b.textContent?.includes('立即学习')) b.click(); }); }; setTimeout(click, 2000); setInterval(click, 30000); } // ==================== 悬浮面板 ==================== function createPanel() { if (self !== top) return; const p = document.createElement('div'); p.id = 'huayi-panel'; p.style.cssText = ` position:fixed;top:20px;right:20px;width:40px;height:40px; background:#4CAF50;border-radius:50%;box-shadow:0 2px 8px rgba(0,0,0,0.2); z-index:99999;cursor:pointer;display:flex;align-items:center;justify-content:center; font-size:20px;color:white; `; document.body.appendChild(p); p.onclick = e => { e.stopPropagation(); togglePanel(); }; document.onclick = () => isExpanded && collapsePanel(); } function togglePanel() { isExpanded ? collapsePanel() : expandPanel(); } function expandPanel() { const p = document.getElementById('huayi-panel'); isExpanded = true; p.style.cssText = ` position:fixed;top:20px;right:20px;width:260px;height:auto; background:#4CAF50;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.3); z-index:99999;padding:12px;font-size:12px;color:white; `; const courses = safeParseJSON(localStorage.getItem('huayi_course_list'), []); const cwid = new URLSearchParams(location.search).get('cwid'); const cur = courses.find(c => c.cwid === cwid); const status = p.getAttribute('data-status') || 'init'; const map = { init:'初始化', playing:'播放中', completed:'已完成', face:'刷脸中', list:'课程列表', exam:'考试处理', error:'未适配' }; p.innerHTML = `
华医网自动播放脚本
状态: ${map[status]}
速度: 1.0x
${cur ? `
当前: ${cur.title.slice(0,16)}...
` : ''}
课程数: ${courses.length}
`; document.getElementById('nextBtn').onclick = e => { e.stopPropagation(); proceedToNext(); }; } function collapsePanel() { const p = document.getElementById('huayi-panel'); isExpanded = false; p.style.cssText = ` position:fixed;top:20px;right:20px;width:40px;height:40px; background:#4CAF50;border-radius:50%;box-shadow:0 2px 8px rgba(0,0,0,0.2); z-index:99999;cursor:pointer;display:flex;align-items:center;justify-content:center; font-size:20px;color:white; `; setPanelStatus(p.getAttribute('data-status') || 'init'); p.onclick = e => { e.stopPropagation(); togglePanel(); }; } function setPanelStatus(status) { const p = document.getElementById('huayi-panel'); if (!p) return; p.setAttribute('data-status', status); if (isExpanded) return; const cfg = { init: { c:'#9E9E9E', i:'⚪' }, playing: { c:'#4CAF50', i:'▶️' }, completed: { c:'#2196F3', i:'✅' }, face: { c:'#FF9800', i:'👤' }, list: { c:'#9C27B0', i:'📋' }, exam: { c:'#FF5722', i:'📝' }, error: { c:'#F44336', i:'❌' } }; const { c, i } = cfg[status] || cfg.init; p.style.background = c; p.textContent = i; } })();