// ==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;
}
}
}
};
})();