Firefox环境下网站AFK视频自动续播的技术实现方案咨询
Great question! Your initial plan of searching for the prompt text and triggering a click works, but there are more robust, efficient, and reliable ways to solve this problem. Let’s go through the top alternatives:
1. Use MutationObserver Instead of Polling for Text
Instead of using setInterval to repeatedly scan the DOM for the prompt text (which wastes unnecessary resources), MutationObserver lets you listen for real-time DOM changes and react only when the prompt appears. This is far more performant for long-running browser sessions.
Here’s a quick implementation example for your content script:
// Target the root container where the AFK prompt typically loads (adjust selector to match the site) const targetNode = document.body; // Configure observer to watch for new elements being added anywhere in the DOM const observerConfig = { childList: true, subtree: true, }; // Callback to run when DOM changes are detected const callback = (mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { // Check for the continue button using a mix of text and selector fallbacks const continueBtn = document.querySelector('button:has-text("Are You Still There? Click To Continue Watching")') || document.querySelector('.continue-watching-btn'); // Prioritize class selectors if available if (continueBtn) { continueBtn.click(); // Optional: Disconnect the observer if you only need to handle one prompt, or leave it running for repeats // observer.disconnect(); } } } }; // Initialize and start the observer const observer = new MutationObserver(callback); observer.observe(targetNode, observerConfig);
2. Call the Site’s Native Resume Function Directly
Many sites don’t just rely on a button click to resume playback—they have internal JavaScript functions (like resumeVideo(), continuePlayback(), etc.) that handle the core resume logic. Calling this function directly is often more reliable than simulating a click, since button selectors might change, but core site functions tend to stay consistent.
To access these page-level functions (content scripts run in an isolated context), inject a script into the page’s main context:
// In your content script, inject a script into the page's global context const script = document.createElement('script'); script.textContent = ` // Check if the site's resume function exists (use dev tools to find the exact name) if (window.resumeVideo) { const checkForPrompt = setInterval(() => { const promptIsVisible = document.querySelector('.afk-prompt-container') !== null; if (promptIsVisible) { window.resumeVideo(); // Optional: Stop checking after the first trigger if you don't expect repeats // clearInterval(checkForPrompt); } }, 1000); } `; document.body.appendChild(script);
Pro tip: Use your browser’s dev tools to inspect the site’s JavaScript and locate the exact resume function name.
3. Block the AFK Detection at the Source
Instead of reacting to the prompt, prevent it from appearing entirely. Some sites trigger AFK pauses by:
- Sending periodic requests to a server to verify user activity
- Listening for extended periods of mouse/keyboard inactivity
You can use Firefox’s webRequest API to intercept and block those detection requests. Add this to your extension’s background script:
browser.webRequest.onBeforeRequest.addListener( (details) => { return { cancel: true }; }, { urls: ["*://example.com/api/afk-check*"] }, // Adjust URL to match the site's detection endpoint ["blocking"] );
Alternatively, simulate subtle user activity to trick the site’s inactivity detector:
// In your content script, simulate occasional mouse movement every 30 seconds setInterval(() => { const event = new MouseEvent('mousemove', { bubbles: true }); document.dispatchEvent(event); }, 30000);
Note: Be cautious with this approach—some sites may flag excessive simulated activity as bot behavior.
4. Use Precise Element Selectors (Instead of Text Search)
Text search can fail if the site supports multiple languages (e.g., the prompt might appear as "¿Sigues ahí?" in Spanish). Instead, use CSS selectors or XPath targeting the button’s attributes (like class, ID, or data attributes) which are far more consistent across locales:
// Example using a CSS class selector (most reliable) const continueBtn = document.querySelector('.continue-playback-btn'); // Example using XPath for text targeting (fallback for sites without consistent classes) const continueBtnXPath = document.evaluate( '//button[contains(text(), "Are You Still There? Click To Continue Watching")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; if (continueBtn) continueBtn.click();
Key Considerations
- Site Updates: Websites often tweak their DOM structure or JS logic, so include fallback selectors/functions to keep your extension working through changes.
- Permissions: Ensure your extension has the necessary permissions (e.g.,
activeTab,webRequest, or host permissions for the target site). - Anti-Bot Measures: Avoid overly aggressive automation—some sites may restrict access if they detect bot-like behavior.
内容的提问来源于stack exchange,提问作者Justin Forthegames

