模拟页面聚焦,防止视频暂停 + 播放结束提醒,适用于雨课堂等平台,风险极低
// ==UserScript==
// @name 视频播放保持焦点 + 播放完提醒(安全二合一)
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 模拟页面聚焦,防止视频暂停 + 播放结束提醒,适用于雨课堂等平台,风险极低
// @match *://*.yuketang.cn/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// --- Configuration ---
// You might need to change these selectors based on your course website.
// Use your browser's developer tools (F12) to inspect the video player and find the correct selector for the play button.
// Common selectors might be:
// 'button.play-button'
// 'div.video-player-controls .play'
// 'video' // Sometimes just interacting with the video element itself works
// 'button[aria-label="Play"]'
const PLAY_BUTTON_SELECTORS = [
'button.play-button',
'div.video-player-controls .play',
'button[aria-label="Play"]',
'button[title="Play"]',
'a.play-button',
'div[role="button"].play-button',
// Add more potential selectors here based on your website
'video', // Include video element itself as a fallback
];
// How often to check for the play button (in milliseconds)
const CHECK_INTERVAL = 1000; // Check every 1 second
// How long to keep checking for the play button (in milliseconds)
const MAX_CHECK_TIME = 30000; // Stop checking after 30 seconds
// --- Auto Play Logic ---
let checkAttempts = 0;
const autoPlayInterval = setInterval(() => {
checkAttempts++;
if (checkAttempts * CHECK_INTERVAL > MAX_CHECK_TIME) {
console.log('AutoPlay script: Max check time reached, stopping auto play check.');
clearInterval(autoPlayInterval);
return;
}
let playButtonClicked = false;
for (const selector of PLAY_BUTTON_SELECTORS) {
const element = document.querySelector(selector);
if (element) {
console.log(`AutoPlay script: Found element with selector "${selector}"`, element);
// Check if it's a video element and if it's paused
if (element.tagName === 'VIDEO') {
if (element.paused) {
console.log('AutoPlay script: Video is paused, attempting to play.');
element.play().then(() => {
console.log('AutoPlay script: Video play() successful.');
playButtonClicked = true;
clearInterval(autoPlayInterval); // Stop checking once played
}).catch(error => {
console.warn('AutoPlay script: Video play() failed:', error);
// Continue checking if play failed, maybe it's not ready yet
});
} else {
console.log('AutoPlay script: Video is already playing.');
playButtonClicked = true;
clearInterval(autoPlayInterval); // Stop checking if already playing
}
} else {
// Assume it's a button or clickable element
console.log('AutoPlay script: Found potential play button, attempting to click.');
element.click();
console.log('AutoPlay script: Clicked element.');
playButtonClicked = true;
clearInterval(autoPlayInterval); // Stop checking once clicked
}
if (playButtonClicked) {
break; // Exit the loop if we found and interacted with an element
}
}
}
if (playButtonClicked) {
console.log('AutoPlay script: Auto play action performed.');
} else {
console.log(`AutoPlay script: Play button not found after ${checkAttempts} attempts.`);
}
}, CHECK_INTERVAL);
// --- Prevent Pause on Blur Logic ---
// This part tries to trick the website into thinking the tab is always visible.
// It overrides document.hidden and document.visibilityState properties.
// Note: This might not work on all websites, as some might use other methods to detect focus.
console.log('AutoPlay script: Attempting to prevent pause on blur.');
// Store original properties
const originalDocumentHidden = Object.getOwnPropertyDescriptor(Document.prototype, 'hidden');
const originalDocumentVisibilityState = Object.getOwnPropertyDescriptor(Document.prototype, 'visibilityState');
// Override properties if they exist
if (originalDocumentHidden && originalDocumentHidden.configurable) {
Object.defineProperty(Document.prototype, 'hidden', {
get: function() { return false; }, // Always report as not hidden
configurable: true // Allow redefining later if needed
});
console.log('AutoPlay script: Overrode document.hidden');
} else {
console.warn('AutoPlay script: Could not override document.hidden');
}
if (originalDocumentVisibilityState && originalDocumentVisibilityState.configurable) {
Object.defineProperty(Document.prototype, 'visibilityState', {
get: function() { return 'visible'; }, // Always report as visible
configurable: true // Allow redefining later if needed
});
console.log('AutoPlay script: Overrode document.visibilityState');
} else {
console.warn('AutoPlay script: Could not override document.visibilityState');
}
// You might also need to simulate 'focus' or 'visibilitychange' events periodically
// This is more complex and might not be necessary depending on the website.
// Example (uncomment and adapt if needed):
/*
setInterval(() => {
try {
window.dispatchEvent(new Event('focus'));
document.dispatchEvent(new Event('visibilitychange'));
} catch (e) {
console.warn('AutoPlay script: Failed to dispatch events:', e);
}
}, 5000); // Dispatch events every 5 seconds
*/
console.log('AutoPlay script: Initialization complete.');
})();