// ==UserScript==
// @name TOD🚀全平台网课助手【学习通 U校园ai 知到 英华 仓辉 雨课堂 职教云】【学起 青书 柠檬 睿学 慕享 出头科技 慕华】【国开 广开 上海开放大学】等平台 客服微信:WKWK796 自动刷课
// @namespace https://github.com/wkwk796
// @version 2.6
// @description 🐯全网免费仅做一款脚本🐯】、【🚀已完美兼容、智慧树、中国大学mooc、慕课、雨课堂、新国开、超星、学习通、知到、国家开放大学、蓝墨云、职教云、智慧职教、云班课精品课、山东专技、西财在线剩余网站仅支持部分功能🚀】【半兼容、绎通云、U校园、学堂在线】、【😎完美应付测试,全自动答题,一键完成所有资源学习(视频挨个刷时长不存在滴)、视频倍速😎】、
// @author Wkwk796
// @match *://*.chaoxing.com/*
// @match *://*.zhihuishu.com/*
// @match *://*.chaoxing.com/*
// @match *://mooc1.chaoxing.com/nodedetailcontroller/*
// @match *://*.chaoxing.com/mooc-ans/work/doHomeWorkNew*
// @match *://*.chaoxing.com/work/doHomeWorkNew*
// @match *://*.edu.cn/work/doHomeWorkNew*
// @match *://*.asklib.com/*
// @match *://*.chaoxing.com/*
// @match *://*.hlju.edu.cn/*
// @match *://lms.ouchn.cn/*
// @match *://xczxzdbf.moodle.qwbx.ouchn.cn/*
// @match *://tongyi.aliyun.com/qianwen/*
// @match *://chatglm.cn/*
// @match *://*.zhihuishu.com/*
// @match *://course.ougd.cn/*
// @match *://moodle.syxy.ouchn.cn/*
// @match *://moodle.qwbx.ouchn.cn/*
// @match *://elearning.bjou.edu.cn/*
// @match *://whkpc.hnqtyq.cn:5678/*
// @match *://study.ouchn.cn/*
// @match *://www.51xinwei.com/*
// @match *://*.w-ling.cn/*
// @match *://xuexi.jsou.cn/*
// @match *://*.edu-edu.com/*
// @match *://xuexi.jsou.cn/*
// @match *://spoc-exam.icve.com.cn/*
// @match *://*.icve.com.cn/*
// @match *://zice.cnzx.info/*
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_info
// @grant GM_addStyle
// @grant unsafeWindow
// @grant none
// @license MIT
// @icon https://static.zhihuishu.com/static/img/favicon.ico
// ==/UserScript==
(function() {
'use strict';
// 配置参数
const config = {
mute: true, // 默认静音
autoPlay: true, // 默认自动播放
skipIntro: true, // 跳过片头
introDuration: 5, // 片头时长(秒)
checkInterval: 2000, // 检测间隔(毫秒)
contactInfo: 'wkwk796' // 联系方式
};
// 全局变量
let videoElement = null;
let isPlaying = false;
let isMuted = config.mute;
let lastPlaybackTime = 0;
let checkTimer = null;
let controlPanel = null;
// 初始化函数
function init() {
console.log('学习通自动播放脚本已启动');
// 创建控制面板
createControlPanel();
// 开始检测视频元素
startVideoDetection();
}
// 开始检测视频元素
function startVideoDetection() {
checkTimer = setInterval(() => {
detectVideoElement();
}, config.checkInterval);
}
// 检测视频元素
function detectVideoElement() {
// 查找视频元素
const videos = document.querySelectorAll('video');
if (videos.length > 0) {
videoElement = videos[0];
// 清除检测定时器
clearInterval(checkTimer);
// 初始化视频控制
initVideoControl();
// 更新控制面板状态
updateControlPanel();
console.log('找到视频元素,开始控制');
}
}
// 初始化视频控制
function initVideoControl() {
if (!videoElement) return;
// 设置静音
videoElement.muted = config.mute;
isMuted = config.mute;
// 添加事件监听
videoElement.addEventListener('play', onVideoPlay);
videoElement.addEventListener('pause', onVideoPause);
videoElement.addEventListener('ended', onVideoEnded);
videoElement.addEventListener('timeupdate', onTimeUpdate);
// 尝试自动播放
if (config.autoPlay) {
tryPlayVideo();
}
// 处理鼠标离开暂停问题
handleMouseLeaveIssue();
}
// 尝试播放视频
function tryPlayVideo() {
if (!videoElement) return;
// 如果视频已经暂停,尝试播放
if (videoElement.paused) {
// 现代浏览器需要用户交互才能播放视频,这里模拟点击
simulateUserInteraction();
videoElement.play().then(() => {
console.log('视频播放成功');
}).catch(error => {
console.error('视频播放失败:', error);
// 如果播放失败,尝试其他方法
forcePlayVideo();
});
}
}
// 模拟用户交互
function simulateUserInteraction() {
// 创建一个不可见的按钮并点击
const button = document.createElement('button');
button.style.position = 'absolute';
button.style.top = '-100px';
document.body.appendChild(button);
// 触发点击事件
button.click();
// 移除按钮
setTimeout(() => {
document.body.removeChild(button);
}, 100);
}
// 强制播放视频
function forcePlayVideo() {
if (!videoElement) return;
// 尝试设置currentTime来触发播放
if (videoElement.currentTime < 1) {
videoElement.currentTime = 1;
}
// 使用requestAnimationFrame尝试播放
requestAnimationFrame(() => {
videoElement.play().catch(error => {
console.error('强制播放失败:', error);
// 如果仍然失败,显示提示
showNotification('视频播放需要用户交互,请点击视频区域');
});
});
}
// 处理鼠标离开暂停问题
function handleMouseLeaveIssue() {
// 找到视频容器
const videoContainer = videoElement.closest('.vjs-tech') ||
videoElement.closest('.video-container') ||
videoElement.parentElement;
if (videoContainer) {
// 移除mouseleave事件监听器
const mouseLeaveListeners = getEventListeners(videoContainer).mouseleave;
if (mouseLeaveListeners && mouseLeaveListeners.length > 0) {
mouseLeaveListeners.forEach(listener => {
videoContainer.removeEventListener('mouseleave', listener.listener);
});
console.log('已移除mouseleave事件监听器');
}
// 模拟鼠标一直悬停在视频上
simulateMouseHover(videoContainer);
}
}
// 模拟鼠标悬停
function simulateMouseHover(element) {
const event = new MouseEvent('mousemove', {
bubbles: true,
cancelable: true,
clientX: element.getBoundingClientRect().left + 10,
clientY: element.getBoundingClientRect().top + 10
});
setInterval(() => {
element.dispatchEvent(event);
}, 1000);
}
// 获取事件监听器(需要浏览器支持)
function getEventListeners(element) {
if (window.getEventListeners) {
return window.getEventListeners(element);
}
// 如果浏览器不支持getEventListeners,返回空对象
return {};
}
// 创建控制面板
function createControlPanel() {
// 创建面板容器
controlPanel = document.createElement('div');
controlPanel.id = 'learning-auto-play-panel';
controlPanel.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 15px;
border-radius: 5px;
z-index: 9999;
font-family: Arial, sans-serif;
font-size: 12px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
cursor: pointer;
transition: all 0.3s ease;
`;
// 添加标题
const title = document.createElement('div');
title.textContent = '学习通自动播放';
title.style.fontWeight = 'bold';
title.style.marginBottom = '5px';
controlPanel.appendChild(title);
// 添加状态信息
const status = document.createElement('div');
status.id = 'panel-status';
status.textContent = '初始化中...';
status.style.marginBottom = '5px';
controlPanel.appendChild(status);
// 添加联系方式
const contact = document.createElement('div');
contact.id = 'panel-contact';
contact.textContent = `联系方式: ${config.contactInfo}`;
contact.style.fontSize = '11px';
contact.style.color = '#aaa';
controlPanel.appendChild(contact);
// 添加控制按钮
const controls = document.createElement('div');
controls.id = 'panel-controls';
controls.style.display = 'none';
controls.style.marginTop = '10px';
controls.style.paddingTop = '10px';
controls.style.borderTop = '1px solid rgba(255, 255, 255, 0.2)';
// 静音切换按钮
const muteBtn = document.createElement('button');
muteBtn.id = 'btn-mute';
muteBtn.textContent = isMuted ? '取消静音' : '静音';
muteBtn.style.marginRight = '5px';
muteBtn.style.padding = '3px 8px';
muteBtn.style.border = 'none';
muteBtn.style.borderRadius = '3px';
muteBtn.style.backgroundColor = '#444';
muteBtn.style.color = 'white';
muteBtn.style.cursor = 'pointer';
muteBtn.addEventListener('click', toggleMute);
controls.appendChild(muteBtn);
// 播放/暂停按钮
const playBtn = document.createElement('button');
playBtn.id = 'btn-play';
playBtn.textContent = '播放';
playBtn.style.marginRight = '5px';
playBtn.style.padding = '3px 8px';
playBtn.style.border = 'none';
playBtn.style.borderRadius = '3px';
playBtn.style.backgroundColor = '#444';
playBtn.style.color = 'white';
playBtn.style.cursor = 'pointer';
playBtn.addEventListener('click', togglePlay);
controls.appendChild(playBtn);
// 跳过片头按钮
const skipBtn = document.createElement('button');
skipBtn.id = 'btn-skip';
skipBtn.textContent = '跳过片头';
skipBtn.style.padding = '3px 8px';
skipBtn.style.border = 'none';
skipBtn.style.borderRadius = '3px';
skipBtn.style.backgroundColor = '#444';
skipBtn.style.color = 'white';
skipBtn.style.cursor = 'pointer';
skipBtn.addEventListener('click', skipIntroduction);
controls.appendChild(skipBtn);
controlPanel.appendChild(controls);
// 添加点击事件,展开/收起控制面板
controlPanel.addEventListener('click', toggleControlPanel);
// 添加到页面
document.body.appendChild(controlPanel);
}
// 切换控制面板展开/收起
function toggleControlPanel() {
const controls = document.getElementById('panel-controls');
if (controls.style.display === 'none') {
controls.style.display = 'block';
controlPanel.style.width = '250px';
} else {
controls.style.display = 'none';
controlPanel.style.width = 'auto';
}
}
// 更新控制面板状态
function updateControlPanel() {
if (!controlPanel) return;
const statusElement = document.getElementById('panel-status');
const muteBtn = document.getElementById('btn-mute');
const playBtn = document.getElementById('btn-play');
if (videoElement) {
const statusText = isPlaying ? '正在播放' : '已暂停';
const muteText = isMuted ? '取消静音' : '静音';
const playText = isPlaying ? '暂停' : '播放';
statusElement.textContent = `${statusText} | 音量: ${isMuted ? '0%' : Math.round(videoElement.volume * 100)}%`;
muteBtn.textContent = muteText;
playBtn.textContent = playText;
} else {
statusElement.textContent = '未检测到视频';
}
}
// 切换静音状态
function toggleMute() {
if (!videoElement) return;
isMuted = !isMuted;
videoElement.muted = isMuted;
updateControlPanel();
}
// 切换播放/暂停状态
function togglePlay() {
if (!videoElement) return;
if (videoElement.paused) {
videoElement.play();
} else {
videoElement.pause();
}
}
// 跳过片头
function skipIntroduction() {
if (!videoElement) return;
videoElement.currentTime = config.introDuration;
showNotification(`已跳过${config.introDuration}秒片头`);
}
// 视频播放事件处理
function onVideoPlay() {
isPlaying = true;
updateControlPanel();
console.log('视频开始播放');
}
// 视频暂停事件处理
function onVideoPause() {
// 检查是否是视频结束导致的暂停
if (videoElement && videoElement.currentTime >= videoElement.duration - 0.5) {
return;
}
isPlaying = false;
updateControlPanel();
console.log('视频暂停');
// 如果启用了自动播放,尝试重新播放
if (config.autoPlay) {
setTimeout(() => {
tryPlayVideo();
}, 1000);
}
}
// 视频结束事件处理
function onVideoEnded() {
isPlaying = false;
updateControlPanel();
console.log('视频播放结束');
// 尝试自动播放下一个视频
setTimeout(() => {
tryPlayNextVideo();
}, 2000);
}
// 尝试播放下一个视频
function tryPlayNextVideo() {
// 查找下一个视频按钮
const nextButtons = document.querySelectorAll('.next-btn, .btn-next, .btn-forward');
if (nextButtons.length > 0) {
nextButtons[0].click();
showNotification('正在播放下一个视频');
console.log('已点击下一个视频按钮');
// 重新开始检测视频元素
startVideoDetection();
} else {
showNotification('未找到下一个视频按钮');
console.log('未找到下一个视频按钮');
}
}
// 视频时间更新事件处理
function onTimeUpdate() {
if (!videoElement) return;
// 检查是否需要跳过片头
if (config.skipIntro && videoElement.currentTime <= config.introDuration &&
Math.abs(videoElement.currentTime - lastPlaybackTime) < 0.5) {
videoElement.currentTime = config.introDuration;
showNotification(`已自动跳过${config.introDuration}秒片头`);
console.log('已自动跳过片头');
}
lastPlaybackTime = videoElement.currentTime;
}
// 显示通知
function showNotification(message) {
// 创建通知元素
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 15px;
border-radius: 5px;
z-index: 9999;
font-family: Arial, sans-serif;
font-size: 12px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
`;
notification.textContent = message;
// 添加到页面
document.body.appendChild(notification);
// 3秒后移除通知
setTimeout(() => {
notification.style.opacity = '0';
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
// 页面加载完成后初始化
window.addEventListener('load', init);
// 页面动态内容变化时重新检测
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length > 0 && !videoElement) {
detectVideoElement();
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();