您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
岐黄天使刷课助手的视频播放控制模块,负责视频的自动播放、暂停和状态管理。
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/537083/1594828/%E5%B2%90%E9%BB%84%E5%A4%A9%E4%BD%BF%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B%20-%20%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E6%A8%A1%E5%9D%97.js
// ==UserScript== // @name 岐黄天使刷课助手 - 视频播放模块 // @namespace http://tampermonkey.net/qhtx-modules // @version 1.3.0 // @description 岐黄天使刷课助手的视频播放控制模块,负责视频的自动播放、暂停和状态管理。 // @author AI助手 // ==/UserScript== // 视频播放模块 (function() { 'use strict'; // 切换自动学习状态 window.toggleAutoLearn = function() { // 获取当前状态,如果GM_getValue不可用,则使用localStorage let isRunning; if (typeof GM_getValue !== 'undefined') { isRunning = GM_getValue('qh-is-running', false); } else { isRunning = localStorage.getItem('qh-is-running') === 'true'; } // 切换状态 isRunning = !isRunning; // 保存新状态 if (typeof GM_setValue !== 'undefined') { GM_setValue('qh-is-running', isRunning); } else { localStorage.setItem('qh-is-running', isRunning.toString()); } console.log('切换自动学习状态:', isRunning ? '开始' : '暂停'); if (isRunning) { // 开始自动学习 updateStatus('自动学习已开始'); // 设置定时器,定期检查和播放视频 if (!window.qh.autoPlayInterval) { window.qh.autoPlayInterval = setInterval(autoPlayVideo, 5000); // 立即执行一次 setTimeout(autoPlayVideo, 500); } // 尝试播放所有视频 setTimeout(() => { try { // 直接调用视频播放函数 const videos = document.querySelectorAll('video'); if (videos.length > 0) { updateStatus('找到视频,尝试播放'); console.log('找到视频,尝试播放'); videos.forEach(video => { // 设置视频属性 video.loop = true; video.muted = true; video.playbackRate = 2.0; // 尝试播放视频 try { const playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(() => { console.log('视频播放成功'); updateStatus('视频播放成功'); }).catch(error => { console.error('视频播放失败:', error); // 尝试使用其他方法播放 setTimeout(() => { try { video.play(); } catch (e) { console.error('重试播放失败:', e); } }, 1000); }); } } catch (e) { console.error('播放视频出错:', e); } }); } // 检查iframe中的视频 const frames = document.querySelectorAll('iframe'); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; const frameVideos = frameDoc.querySelectorAll('video'); if (frameVideos.length > 0) { updateStatus('在iframe中找到视频,尝试播放'); console.log('在iframe中找到视频,尝试播放'); frameVideos.forEach(video => { // 设置视频属性 video.loop = false; // 不循环播放 video.muted = true; // 不修改播放速度,使用默认速度 // 尝试播放视频 try { const playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(() => { console.log('iframe视频播放成功'); updateStatus('iframe视频播放成功'); }).catch(error => { console.error('iframe视频播放失败:', error); // 尝试使用其他方法播放 setTimeout(() => { try { video.play(); } catch (e) { console.error('重试播放iframe视频失败:', e); } }, 1000); }); } } catch (e) { console.error('播放iframe视频出错:', e); } }); } } catch (e) { console.error('无法访问iframe内容:', e); } } } catch (e) { console.error('播放视频出错:', e); } }, 1000); } else { // 暂停自动学习 updateStatus('自动学习已暂停'); // 清除定时器 if (window.qh.autoPlayInterval) { clearInterval(window.qh.autoPlayInterval); window.qh.autoPlayInterval = null; } // 暂停所有视频 pauseAllVideos(); } // 更新按钮状态 updateButtonStatus(); }; // 播放iframe中的视频 window.playAllVideos = function() { // 尝试播放iframe中的视频 const frames = document.querySelectorAll('iframe'); frames.forEach(frame => { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; const frameVideos = frameDoc.querySelectorAll('video'); frameVideos.forEach(video => { // 设置视频属性 video.loop = false; // 不循环播放 video.muted = true; // 不修改播放速度,使用默认速度 // 尝试播放视频 try { const playPromise = video.play(); // 处理播放承诺 if (playPromise !== undefined) { playPromise.then(() => { console.log('iframe视频播放成功'); }).catch(error => { console.error('iframe视频播放失败:', error); // 尝试使用其他方法播放 setTimeout(() => { try { video.play(); } catch (e) { console.error('重试播放iframe视频失败:', e); } }, 1000); }); } } catch (e) { console.error('播放iframe视频出错:', e); } }); } catch (e) { console.error('无法访问iframe内容:', e); } }); }; // 暂停所有视频 window.pauseAllVideos = function() { // 尝试暂停iframe中的视频 const frames = document.querySelectorAll('iframe'); frames.forEach(frame => { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; const frameVideos = frameDoc.querySelectorAll('video'); frameVideos.forEach(video => { try { video.pause(); } catch (e) { console.error('暂停iframe视频出错:', e); } }); } catch (e) { console.error('无法访问iframe内容:', e); } }); }; // 主要功能:自动播放视频 window.autoPlayVideo = function() { try { // 检查是否应该播放视频 let isRunning; if (typeof GM_getValue !== 'undefined') { isRunning = GM_getValue('qh-is-running', false); } else { isRunning = localStorage.getItem('qh-is-running') === 'true'; } if (!isRunning) { // 如果不是自动播放状态,则不执行后续操作 return; } // 更新状态 updateStatus('正在检测视频...'); console.log('正在检测视频...'); // 尝试查找视频元素 let foundVideo = false; // 2. 检查所有iframe中的视频 const frames = document.querySelectorAll('iframe'); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; const frameVideos = frameDoc.querySelectorAll('video'); if (frameVideos.length > 0) { updateStatus('在iframe中找到视频,尝试播放'); console.log('在iframe中找到视频,尝试播放'); frameVideos.forEach(video => { // 设置视频属性 video.loop = false; // 不循环播放 video.muted = true; // 尝试获取视频标题 try { // 尝试从iframe文档中获取标题 let videoTitle = ''; // 尝试从iframe标题获取 if (frameDoc.title && !frameDoc.title.includes('岐黄天使') && !frameDoc.title.includes('登录')) { videoTitle = frameDoc.title; } // 尝试从视频元素的父元素或周围元素获取标题 if (!videoTitle) { const videoContainer = video.closest('.video-container, .player-container, .course-player'); if (videoContainer) { const titleElement = videoContainer.querySelector('.title, .video-title, .course-title'); if (titleElement) { videoTitle = titleElement.textContent.trim(); } } } // 尝试从iframe中的常见标题元素获取 if (!videoTitle) { const titleSelectors = [ '.video-title', '.course-title', '.title', 'h1.title', 'h2.title', 'h3.title', '.course-name', '.video-name', '.lesson-title', '#courseTitle', '#videoTitle', '#lessonTitle' ]; for (const selector of titleSelectors) { const titleElement = frameDoc.querySelector(selector); if (titleElement && titleElement.textContent.trim()) { videoTitle = titleElement.textContent.trim(); break; } } } // 如果找到标题,更新当前课程 if (videoTitle) { updateCurrentCourse(videoTitle); } else { // 如果没有找到标题,尝试自动检测 updateCurrentCourse(null); } } catch (e) { console.error('获取iframe视频标题出错:', e); // 出错时也尝试自动检测 updateCurrentCourse(null); } // 尝试播放视频 try { const playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(() => { console.log('iframe视频播放成功'); updateStatus('iframe视频播放成功'); // 再次尝试更新课程信息 updateCurrentCourse(null); }).catch(error => { console.error('iframe视频播放失败:', error); // 尝试使用其他方法播放 setTimeout(() => { try { video.play(); } catch (e) { console.error('重试播放iframe视频失败:', e); } }, 1000); }); } } catch (e) { console.error('播放iframe视频出错:', e); } // 监听进度 video.addEventListener('timeupdate', function() { const progress = Math.floor((video.currentTime / video.duration) * 100); updateProgress(progress); }); // 监听视频结束事件,自动切换到下一个视频 // 移除之前可能存在的事件监听器,避免重复添加 video.removeEventListener('ended', window.qh.videoEndedHandler); // 创建新的事件处理函数并保存到全局变量 window.qh.videoEndedHandler = function() { // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略视频结束事件'); return; } console.log('iframe视频播放完成,准备切换到下一个课程'); updateStatus('视频播放完成,准备切换到下一个课程'); // 设置导航状态标志 window.qh.isNavigating = true; // 延迟一秒后切换到下一课 setTimeout(() => { // 查找当前课程元素 const currentCourse = document.querySelector('.new_bg.active, .course-item.active, .lesson-item.active'); if (currentCourse) { // 查找下一个课程元素 let nextCourse = currentCourse.nextElementSibling; while (nextCourse && !(nextCourse.classList.contains('new_bg') || nextCourse.classList.contains('course-item') || nextCourse.classList.contains('lesson-item'))) { nextCourse = nextCourse.nextElementSibling; } // 如果找到下一个课程,点击它 if (nextCourse) { nextCourse.click(); } else { // 如果没有找到,尝试使用navigateToNextCourse函数 if (typeof navigateToNextCourse === 'function') { navigateToNextCourse(); } } } else { // 如果没有当前课程元素,尝试使用navigateToNextCourse函数 if (typeof navigateToNextCourse === 'function') { navigateToNextCourse(); } } // 5秒后重置导航状态标志,避免卡死 setTimeout(() => { window.qh.isNavigating = false; }, 5000); }, 1000); }; // 添加新的事件监听器 video.addEventListener('ended', window.qh.videoEndedHandler); }); foundVideo = true; } } catch (e) { console.error('无法访问iframe内容:', e); } } // 3. 如果没有找到视频,尝试查找未完成的课程 if (!foundVideo) { updateStatus('未找到视频,尝试查找未完成的课程'); console.log('未找到视频,尝试查找未完成的课程'); // 尝试在当前页面查找未完成的课程 findAndClickUnfinishedCourse(document); // 尝试在iframe中查找未完成的课程 for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; findAndClickUnfinishedCourse(frameDoc); } catch (e) { console.error('无法访问iframe内容:', e); } } } // 4. 关闭可能出现的弹窗 closePopups(document); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; closePopups(frameDoc); } catch (e) { console.error('无法访问iframe内容:', e); } } // 5. 检查进度指示器 checkProgressIndicator(document); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; checkProgressIndicator(frameDoc); } catch (e) { console.error('无法访问iframe内容:', e); } } // 6. 收集课程链接 if (typeof collectCourseLinks === 'function') { collectCourseLinks(document); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; collectCourseLinks(frameDoc); } catch (e) { console.error('无法访问iframe内容:', e); } } } } catch (e) { console.error('自动播放视频出错:', e); updateStatus('自动播放视频出错: ' + e.message); } }; // 查找并点击未完成的课程 window.findAndClickUnfinishedCourse = function(doc) { // 查找未完成的视频链接 const unfinishedLinks = doc.querySelectorAll('.append-plugin-tip > a, .content-unstart a, .content-learning a'); if (unfinishedLinks.length > 0) { updateStatus('找到未完成的课程,即将播放'); // 收集所有课程链接,用于上一课/下一课导航 if (typeof collectCourseLinks === 'function') { collectCourseLinks(doc); } // 点击第一个未完成的课程 try { unfinishedLinks[0].click(); } catch (e) { console.error('点击未完成课程失败:', e); updateStatus('点击未完成课程失败'); } } else { updateStatus('未找到未完成的课程,可能已全部完成'); // 检查是否有课程列表 const coursesInList = doc.querySelectorAll('.mycourse-row'); if (coursesInList.length > 0) { // 收集课程列表 if (typeof collectCoursesFromList === 'function') { collectCoursesFromList(doc); } // 遍历课程列表,查找未完成的课程 for (let i = 0; i < coursesInList.length; i++) { const courseRow = coursesInList[i]; const courseState = courseRow.innerText.includes('未完成') || courseRow.innerText.includes('未开始'); if (courseState) { updateStatus('在课程列表中找到未完成课程,即将打开'); try { const courseLink = courseRow.querySelector('a'); if (courseLink) { courseLink.click(); break; } } catch (e) { console.error('点击课程列表中的未完成课程失败:', e); } } } } } }; // 检查进度指示器 window.checkProgressIndicator = function(doc) { // 首先尝试从<div class="jc_hd w-80">当前视频已观看时长:<span id="schedule">100%</span>获取进度 const scheduleElement = doc.getElementById('schedule'); if (scheduleElement) { const progressText = scheduleElement.textContent.trim(); const progressMatch = progressText.match(/(\d+)%/); if (progressMatch && progressMatch[1]) { const progress = parseInt(progressMatch[1]); console.log('从schedule元素获取到进度:', progress + '%'); updateProgress(progress); // 如果进度为100%,自动切换到下一个课程 if (progress === 100) { // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略进度100%事件'); return; } console.log('当前视频已完成,准备切换到下一个课程'); updateStatus('视频播放完成,准备切换到下一个课程'); // 设置导航状态标志 window.qh.isNavigating = true; // 延迟一秒后切换到下一课 setTimeout(() => { // 使用navigateToNextCourse函数切换到下一课 if (typeof navigateToNextCourse === 'function') { navigateToNextCourse(); } // 5秒后重置导航状态标志,避免卡死 setTimeout(() => { window.qh.isNavigating = false; }, 5000); }, 1000); } return; } } // 如果没有找到schedule元素,尝试其他进度指示器 const progressIndicator = doc.getElementById('realPlayVideoTime'); if (progressIndicator) { const progress = parseInt(progressIndicator.innerText); updateProgress(progress); // 如果进度为100%,自动切换到下一个课程 if (progress === 100) { // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略进度100%事件'); return; } console.log('当前视频已完成,准备切换到下一个课程'); updateStatus('视频播放完成,准备切换到下一个课程'); // 设置导航状态标志 window.qh.isNavigating = true; // 延迟一秒后切换到下一课 setTimeout(() => { // 使用navigateToNextCourse函数切换到下一课 if (typeof navigateToNextCourse === 'function') { navigateToNextCourse(); } // 5秒后重置导航状态标志,避免卡死 setTimeout(() => { window.qh.isNavigating = false; }, 5000); }, 1000); } } // 尝试查找其他可能的进度指示器 const jcHdElements = doc.querySelectorAll('.jc_hd'); for (const jcHd of jcHdElements) { if (jcHd.textContent.includes('当前视频已观看时长')) { const progressText = jcHd.textContent; const progressMatch = progressText.match(/(\d+)%/); if (progressMatch && progressMatch[1]) { const progress = parseInt(progressMatch[1]); console.log('从jc_hd元素获取到进度:', progress + '%'); updateProgress(progress); // 如果进度为100%,自动切换到下一个课程 if (progress === 100) { // 防止重复触发 if (window.qh.isNavigating) { console.log('导航已在进行中,忽略进度100%事件'); return; } console.log('当前视频已完成,准备切换到下一个课程'); updateStatus('视频播放完成,准备切换到下一个课程'); // 设置导航状态标志 window.qh.isNavigating = true; // 延迟一秒后切换到下一课 setTimeout(() => { // 使用navigateToNextCourse函数切换到下一课 if (typeof navigateToNextCourse === 'function') { navigateToNextCourse(); } // 5秒后重置导航状态标志,避免卡死 setTimeout(() => { window.qh.isNavigating = false; }, 5000); }, 1000); } return; } } } }; })();