您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
岐黄天使刷课助手的视频播放页面导航模块,负责视频播放页面的上一课/下一课功能。
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/537082/1595111/videoNavigation.js
// ==UserScript== // @name 岐黄天使刷课助手 - 视频导航模块 // @namespace http://tampermonkey.net/qhtx-modules // @version 1.3.1 // @description 岐黄天使刷课助手的视频播放页面导航模块,负责视频播放页面的上一课/下一课功能。 // @author AI助手 // ==/UserScript== // 视频导航模块 - 专门处理视频播放页面的导航 (function() { 'use strict'; // 初始化视频导航 window.initVideoNavigation = function() { console.log('初始化视频导航'); // 创建导航按钮 createNavigationButtons(); // 监听视频结束事件 listenVideoEnd(); }; // 创建导航按钮 function createNavigationButtons() { // 检查是否已存在导航按钮 if (document.querySelector('.qh-nav-buttons')) { console.log('导航按钮已存在,无需创建'); return; } console.log('创建导航按钮'); // 创建导航按钮容器 const navContainer = document.createElement('div'); navContainer.className = 'qh-nav-buttons'; navContainer.style.cssText = ` position: fixed; bottom: 20px; left: 0; right: 0; display: flex; justify-content: space-between; padding: 0 36px; z-index: 9999; `; // 创建上一课按钮 const prevButton = document.createElement('div'); prevButton.className = 'qh-prev-btn'; prevButton.textContent = '上一课'; prevButton.style.cssText = ` padding: 10px 20px; background-color: #40b65a; color: white; border-radius: 5px; cursor: pointer; text-align: center; user-select: none; `; // 创建下一课按钮 const nextButton = document.createElement('div'); nextButton.className = 'qh-next-btn'; nextButton.textContent = '下一课'; nextButton.style.cssText = ` padding: 10px 20px; background-color: #40b65a; color: white; border-radius: 5px; cursor: pointer; text-align: center; user-select: none; `; // 添加按钮到容器 navContainer.appendChild(prevButton); navContainer.appendChild(nextButton); // 添加容器到页面 document.body.appendChild(navContainer); // 绑定事件 prevButton.addEventListener('click', function() { navigateToPrevVideo(); }); nextButton.addEventListener('click', function() { navigateToNextVideo(); }); console.log('导航按钮创建完成'); } // 监听视频结束事件 function listenVideoEnd() { // 定义视频结束处理函数 window.videoEndHandler = function() { console.log('视频播放结束,准备切换到下一个视频'); // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略视频结束事件'); return; } // 延迟一秒后切换到下一课,避免与其他事件冲突 setTimeout(() => { navigateToNextVideo(); }, 1000); }; // 查找并监听所有视频元素 function findAndListenVideos() { console.log('查找视频元素并添加结束事件监听器'); // 查找页面中的视频元素 const videoElements = document.querySelectorAll('video'); let foundVideos = false; videoElements.forEach(video => { // 移除之前可能存在的事件监听器 video.removeEventListener('ended', window.videoEndHandler); // 添加事件监听器 video.addEventListener('ended', window.videoEndHandler); console.log('已为视频添加结束事件监听器'); foundVideos = true; // 监听视频进度 monitorVideoProgress(video); }); // 如果没有找到视频元素,尝试在iframe中查找 if (!foundVideos) { const iframes = document.querySelectorAll('iframe'); iframes.forEach(iframe => { try { if (!iframe.contentDocument && iframe.contentWindow) { console.log('尝试通过contentWindow访问iframe内容'); const iframeDoc = iframe.contentWindow.document; processIframeVideos(iframeDoc); } else if (iframe.contentDocument) { console.log('尝试通过contentDocument访问iframe内容'); const iframeDoc = iframe.contentDocument; processIframeVideos(iframeDoc); } else { console.log('无法访问iframe内容,可能是跨域限制'); } } catch (e) { console.error('访问iframe内容时出错:', e); } }); } } // 处理iframe中的视频 function processIframeVideos(iframeDoc) { if (!iframeDoc) { console.log('iframe文档为空'); return; } const iframeVideos = iframeDoc.querySelectorAll('video'); if (iframeVideos.length > 0) { console.log(`在iframe中找到 ${iframeVideos.length} 个视频元素`); iframeVideos.forEach(video => { // 移除之前可能存在的事件监听器 video.removeEventListener('ended', window.videoEndHandler); // 添加事件监听器 video.addEventListener('ended', window.videoEndHandler); console.log('已为iframe视频添加结束事件监听器'); // 监听视频进度 monitorVideoProgress(video); }); } else { console.log('在iframe中未找到视频元素'); } } // 监听视频进度,处理视频结束但未触发ended事件的情况 function monitorVideoProgress(video) { // 创建进度监听器 const progressInterval = setInterval(() => { if (!video || video.paused || video.ended || !video.duration) { return; } // 计算进度百分比 const progress = Math.floor((video.currentTime / video.duration) * 100); // 如果进度接近100%(大于等于99%),认为视频已结束 if (progress >= 99) { console.log('视频进度达到99%以上,视为已结束'); clearInterval(progressInterval); // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略视频进度事件'); return; } // 延迟一秒后切换到下一课 setTimeout(() => { navigateToNextVideo(); }, 1000); } }, 2000); // 每2秒检查一次 // 保存interval ID,以便在需要时清除 if (!window.qh.progressIntervals) { window.qh.progressIntervals = []; } window.qh.progressIntervals.push(progressInterval); } // 初始查找视频 findAndListenVideos(); // 使用MutationObserver监听DOM变化,处理动态加载的视频 const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { // 检查是否添加了视频元素或iframe const hasNewVideo = Array.from(mutation.addedNodes).some(node => node.nodeName === 'VIDEO' || (node.querySelectorAll && node.querySelectorAll('video').length > 0) || node.nodeName === 'IFRAME' || (node.querySelectorAll && node.querySelectorAll('iframe').length > 0) ); if (hasNewVideo) { console.log('检测到新的视频元素或iframe被添加到DOM,重新查找视频'); findAndListenVideos(); } } }); }); // 配置观察选项 const config = { childList: true, subtree: true }; // 开始观察 observer.observe(document.body, config); // 保存observer,以便在需要时断开连接 window.qh.videoObserver = observer; } // 导航到上一个视频 function navigateToPrevVideo() { console.log('导航到上一个视频'); // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略本次请求'); return; } // 设置导航状态 window.qh.isNavigating = true; try { // 尝试查找原始的上一课按钮 const originalPrevButton = document.querySelector('.prev-next .btns:first-child'); if (originalPrevButton) { console.log('找到原始上一课按钮,模拟点击'); // 模拟点击原始按钮 const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); originalPrevButton.dispatchEvent(clickEvent); } else { console.log('未找到原始上一课按钮,尝试其他方法'); // 尝试使用window.prev函数(如果存在) if (typeof window.prev === 'function') { console.log('使用window.prev函数'); window.prev(); } // 尝试使用脚本中的导航函数 else if (typeof window.navigateToPrevCourse === 'function') { console.log('使用脚本导航函数navigateToPrevCourse'); window.navigateToPrevCourse(); } // 尝试查找其他可能的上一课按钮 else { console.log('尝试查找其他可能的上一课按钮'); // 尝试查找包含"上一"文本的按钮或链接 const prevElements = Array.from(document.querySelectorAll('a, button, div')).filter(el => el.textContent && el.textContent.includes('上一') && getComputedStyle(el).display !== 'none' ); if (prevElements.length > 0) { console.log('找到可能的上一课元素,点击第一个'); prevElements[0].click(); } else { console.log('未找到任何可能的上一课元素'); alert('无法导航到上一课,请手动切换'); } } } } catch (e) { console.error('导航到上一课出错:', e); } // 5秒后重置导航状态 setTimeout(() => { window.qh.isNavigating = false; }, 5000); } // 导航到上一课的兼容函数(与UI模块保持一致) function navigateToPrevCourse() { console.log('[视频导航] 调用 navigateToPrevCourse (兼容函数)'); navigateToPrevVideo(); } // 导航到下一个视频 function navigateToNextVideo() { console.log('导航到下一个视频'); // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略本次请求'); return; } // 设置导航状态 window.qh.isNavigating = true; try { // 尝试查找原始的下一课按钮 const originalNextButton = document.querySelector('.prev-next .btns:last-child'); if (originalNextButton) { console.log('找到原始下一课按钮,模拟点击'); // 模拟点击原始按钮 const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); originalNextButton.dispatchEvent(clickEvent); } else { console.log('未找到原始下一课按钮,尝试其他方法'); // 尝试使用window.next函数(如果存在) if (typeof window.next === 'function') { console.log('使用window.next函数'); window.next(); } // 尝试使用脚本中的导航函数 else if (typeof window.navigateToNextCourse === 'function') { console.log('使用脚本导航函数navigateToNextCourse'); window.navigateToNextCourse(); } // 尝试查找其他可能的下一课按钮 else { console.log('尝试查找其他可能的下一课按钮'); // 尝试查找包含"下一"文本的按钮或链接 const nextElements = Array.from(document.querySelectorAll('a, button, div')).filter(el => el.textContent && el.textContent.includes('下一') && getComputedStyle(el).display !== 'none' ); if (nextElements.length > 0) { console.log('找到可能的下一课元素,点击第一个'); nextElements[0].click(); } else { console.log('未找到任何可能的下一课元素'); alert('无法导航到下一课,请手动切换'); } } } } catch (e) { console.error('导航到下一课出错:', e); } // 5秒后重置导航状态 setTimeout(() => { window.qh.isNavigating = false; }, 5000); } // 导航到下一课的兼容函数(与UI模块保持一致) function navigateToNextCourse() { console.log('[视频导航] 调用 navigateToNextCourse (兼容函数)'); navigateToNextVideo(); } // 导出函数 window.navigateToPrevVideo = navigateToPrevVideo; window.navigateToNextVideo = navigateToNextVideo; window.navigateToPrevCourse = navigateToPrevCourse; window.navigateToNextCourse = navigateToNextCourse; })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址