您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
带浮动控制面板的Plyr视频控制器(播放时触发跳转)
当前为
// ==UserScript== // @name Plyr Video Controller Pro // @namespace http://tampermonkey.net/ // @version 1.4 // @description 带浮动控制面板的Plyr视频控制器(播放时触发跳转) // @author glenn // @match http://dxzx.ouc.edu.cn/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @run-at document-end // ==/UserScript== (function() { 'use strict'; // 配置存储 const config = { autoSkip: GM_getValue('autoSkip', true), enableSeek: GM_getValue('enableSeek', true), playbackSpeed: GM_getValue('speed', 2.0), skipDelay: GM_getValue('delay', 100), debugMode: GM_getValue('debug', true) }; // 添加浮动面板样式(保持原图简洁风格) GM_addStyle(` #plyr-control-panel { position: fixed; bottom: 20px; right: 20px; z-index: 9999; background: white; color: black; padding: 10px; border-radius: 5px; font-family: monospace; box-shadow: 0 0 5px rgba(0,0,0,0.3); border: 1px solid #ddd; font-size: 13px; } #plyr-control-panel h3 { margin: 0 0 8px 0; color: #333; font-size: 14px; } .control-row { margin-bottom: 8px; display: flex; align-items: center; } .control-label { margin-right: 10px; min-width: 100px; } .control-btn { background: #f0f0f0; border: 1px solid #ccc; color: #333; padding: 3px 8px; border-radius: 3px; cursor: pointer; font-size: 12px; margin-left: 5px; } .control-btn:hover { background: #e0e0e0; } .control-checkbox { margin-right: 5px; } .speed-input { width: 40px; margin-left: 5px; } `); // 创建浮动控制面板(保持原图风格) function createControlPanel() { const panel = document.createElement('div'); panel.id = 'plyr-control-panel'; panel.innerHTML = ` <h3>Plyr Controller</h3> <div class="control-row"> <label class="control-label"> <input type="checkbox" class="control-checkbox" id="auto-skip" ${config.autoSkip ? 'checked' : ''}> Auto Skip </label> </div> <div class="control-row"> <label class="control-label"> <input type="checkbox" class="control-checkbox" id="enable-seek" ${config.enableSeek ? 'checked' : ''}> Enable Seek </label> </div> <div class="control-row"> <span class="control-label">Speed:</span> <input type="number" class="speed-input" id="speed-control" min="0.5" max="4" step="0.5" value="${config.playbackSpeed}"> </div> <div class="control-row"> <button class="control-btn" id="apply-btn">Apply</button> <button class="control-btn" id="reset-btn">Reset</button> </div> `; document.body.appendChild(panel); // 事件监听 $('#apply-btn').click(applySettings); $('#reset-btn').click(resetVideo); } // 应用设置 function applySettings() { config.autoSkip = $('#auto-skip').is(':checked'); config.enableSeek = $('#enable-seek').is(':checked'); config.playbackSpeed = parseFloat($('#speed-control').val()); GM_setValue('autoSkip', config.autoSkip); GM_setValue('enableSeek', config.enableSeek); GM_setValue('speed', config.playbackSpeed); if (window.currentPlayer) { setupPlayerHooks(window.currentPlayer); } } // 重置视频 function resetVideo() { if (window.currentPlayer) { window.currentPlayer.currentTime = 0; window.currentPlayer.play(); } } // 核心跳转逻辑(修改为播放时触发) function setupPlayerHooks(player) { // 1. 移除原有限制 player.off('ended'); player.off('timeupdate'); // 2. 设置播放速度 player.speed = config.playbackSpeed; // 3. 启用进度条 if (config.enableSeek) { player.media.controls = true; player.media.removeAttribute('controlslist'); $('.plyr__progress').css('display', 'block'); } // 4. 播放时跳转逻辑(新增) player.on('play', () => { if (config.autoSkip) { setTimeout(() => { if (player.duration > 0) { player.currentTime = player.duration - 1; log('Triggered auto-skip at play event'); } else { player.on('loadedmetadata', () => { player.currentTime = player.duration - 1; }); } }, config.skipDelay); } }); log('Player hooks initialized'); } // 检测播放器 function detectPlayer() { const video = document.querySelector('video'); if (video) { const checkInterval = setInterval(() => { if (video.plyr) { clearInterval(checkInterval); window.currentPlayer = video.plyr; setupPlayerHooks(video.plyr); } }, 500); } } // 初始化 function init() { createControlPanel(); detectPlayer(); // 监听动态加载 new MutationObserver(detectPlayer).observe(document.body, { childList: true, subtree: true }); } // 启动 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } // 工具函数 function log(message) { if (config.debugMode) console.log(`[PlyrCtrl] ${message}`); } })();