// ==UserScript==
// @name 基金业协会视频自动播放
// @namespace https://www.nekotofu.top/
// @homepage https://www.nekotofu.top/
// @version 1.3.1
// @description 基金业协会视频自动下一个,但题目目前需要自己答。
// @author misaka10032w
// @match *://peixun.amac.org.cn/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=microsoft.com
// @noframes
// @license MIT
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function () {
'use strict';
// 检查浏览器是否支持通知并在页面加载时请求权限
if (!("Notification" in window)) {
console.log("浏览器不支持通知");
} else if (Notification.permission !== "granted") {
Notification.requestPermission().then(permission => {
if (permission !== "granted") {
customLog("用户拒绝了通知权限", "red");
}
});
}
function sendNotification(title, content) {
if (Notification.permission === "granted") {
showNotification(title, content);
} else {
customLog("通知权限未授予,需要点击地址栏左边按钮重置通知权限", "red");
}
}
function showNotification(title, content) {
const notification = new Notification(title, { body: content });
notification.onclick = () => {
// TODO
customLog("用户点击了通知", "green");
};
}
//自定义LOG
function customLog(message, backgroundColor, color = "white") {
console.log(`%c${message}`, `background: ${backgroundColor}; color: ${color}; padding: 2px 4px; border-radius: 2px;`);
}
//关闭弹窗,这个方法不好使了,暂时不想改了,不耽误播放
function closePopup() {
const pop = document.querySelector(".class_float");
if (pop.style.display != "none") {
var close = pop.getElementsByClassName("btn-close")[0]
close.click();
}
}
//获取课程列表
let nowPlaying;
function getCourse() {
const courseList = document.querySelectorAll(".catalog-content a");
const ignoredClasses = ["studied", "test", "testRev", "testScore"];
for (const course of courseList) {
const hasIgnoredClass = ignoredClasses.some(cls => course.classList.contains(cls));
if (!hasIgnoredClass) {
customLog("存在未播放的项,播放列表未完成:", "yellow", "black");
nowPlaying = course;
customLog(nowPlaying.textContent, "yellow", "black");
if (!nowPlaying.classList.contains("cur")) {
customLog("已播放完毕", "green");
nowPlaying.click();
}
return nowPlaying;
}
}
// 所有项都已经播放,播放列表已完成
return false;
}
//注册菜单
const defaultPlaybackRate = 1.0;
let playBackRate = GM_getValue('playBackRate', defaultPlaybackRate);
const defaultMute = true;
let playbackRateMenu = GM_registerMenuCommand(`播放速率:${GM_getValue('playBackRate', defaultPlaybackRate)}`, setPlaybackRate);
let muteMenu = GM_registerMenuCommand(`${GM_getValue('isMute', defaultMute) ? '🔇' : '🔊'} 是否静音播放`, toggleMute);
function setPlaybackRate() {
const newRate = prompt('请输入新的播放速率,不建议太高,可能会被检测:', playBackRate);
if (newRate !== null) {
playBackRate = parseFloat(newRate);
GM_setValue('playBackRate', playBackRate);
updateMenuCommands();
}
}
function toggleMute() {
let isSetMute = GM_getValue('isMute', defaultMute);
GM_setValue('isMute', !isSetMute);
updateMenuCommands();
}
function updateMenuCommands() {
GM_unregisterMenuCommand(playbackRateMenu);
GM_unregisterMenuCommand(muteMenu);
playbackRateMenu = GM_registerMenuCommand(`播放速率:${GM_getValue('playBackRate', defaultPlaybackRate)}`, setPlaybackRate);
muteMenu = GM_registerMenuCommand(`${GM_getValue('isMute', defaultMute) ? '🔇' : '🔊'} 是否静音播放`, toggleMute);
}
//注册播放器事件
function setupVideoPlayerEvents(player) {
player.addEventListener("play", function () {
customLog("视频开始播放", "green");
});
player.addEventListener("pause", function () {
customLog("视频暂停,将在1000ms后继续播放", "red");
setTimeout(() => { player.play(); }, 1000);
});
player.addEventListener("ended", function () {
customLog("视频播放结束", "green");
});
player.addEventListener("timeupdate", function () {
const currentplaybackRate = player.playbackRate;
const isSetMute = GM_getValue('isMute', defaultMute);
if (player.muted != isSetMute) {
player.muted = isSetMute;
}
if (currentplaybackRate != playBackRate) {
player.playbackRate = playBackRate;
}
})
}
function monitorPlayback(player) {
let maxTime = 0;
setInterval(() => {
const currentTime = player.currentTime.toFixed(0);
const duration = player.duration.toFixed(0);
//console.log(`当前时间: ${currentTime} / 总时长: ${duration}`);
//如果当前播放等于时长并且nowPlaying不为false(为文本代表有课程未看)则重新加载,防止更新延迟导致重看
if (currentTime == duration && nowPlaying) {
setTimeout(() => {
location.reload();
}, 1000);
} else if (currentTime != currentTime && player.paused) {
player.play();
}
//记录一下当前时间,如果最新时间突然变小,证明视频被重新播放了
customLog(`记录的时间:${maxTime}\n现在的时间:${currentTime}`, "green");
maxTime = Number(currentTime) >= maxTime ? Number(currentTime) : (location.reload(), maxTime);
}, 1000);
}
//播放处理
if (document.querySelectorAll(".catalog-content a").length != 0) {
nowPlaying = getCourse();
//检查是否播放完毕,class包含studied即播放完毕
if (!nowPlaying) {
sendNotification("当前课程播放完毕!", "当前课程列表播放完毕,请考试或者切换下一个课程!")
return true
}
//检查iframe,网站的播放器是个iframe,什么鬼写法
var iframe = document.querySelector('iframe');
let checkInterval = setInterval(function () {
iframe = document.querySelector('iframe');
if (iframe) {
let iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
let player = iframeDocument.getElementsByTagName("video")[0];
console.log('找到播放器!:', player);
setupVideoPlayerEvents(player);
monitorPlayback(player)
player.muted = true;
player.play();
clearInterval(checkInterval);
}
}, 500);
}
})();