Greasy Fork

来自缓存

Greasy Fork is available in English.

flyvideo

为页面视频添加快进、快退、暂停控制按钮

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @license MIT
// @name         flyvideo
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  为页面视频添加快进、快退、暂停控制按钮
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 配置项
    let skipSeconds = 10; // 默认快进/快退秒数

    // 样式
    const styles = `
        #video-controller {
            position: fixed;
            bottom: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 8px 12px;
            border-radius: 10px;
            z-index: 999999;
            display: flex;
            gap: 8px;
            align-items: center;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
        }

        #video-controller button {
            background: #4CAF50;
            color: white;
            border: none;
            padding: 5px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 20px;
            transition: all 0.3s;
            line-height: 1;
            min-width: auto;
        }

        #video-controller button:hover {
            background: #45a049;
            transform: scale(1.05);
        }

        #video-controller button.pause {
            background: #f44336;
        }

        #video-controller button.pause:hover {
            background: #da190b;
        }

        #video-controller button.fullscreen {
            background: #2196F3;
        }

        #video-controller button.fullscreen:hover {
            background: #0b7dda;
        }

        #video-controller input {
            width: 40px;
            padding: 5px;
            border: none;
            border-radius: 5px;
            text-align: center;
            font-size: 14px;
        }

        #video-controller label {
            color: white;
            font-size: 14px;
            margin-left: 5px;
        }

        #video-controller .video-info {
            color: white;
            font-size: 12px;
            margin-left: 5px;
        }
    `;

    // 添加样式到页面
    const styleSheet = document.createElement('style');
    styleSheet.textContent = styles;
    document.head.appendChild(styleSheet);

    // 查找视频元素
    function findVideos() {
        return document.querySelectorAll('video');
    }

    // 创建控制面板
    function createController(video) {
        // 检查是否已存在控制器
        if (document.getElementById('video-controller')) {
            return;
        }

        const controller = document.createElement('div');
        controller.id = 'video-controller';

        controller.innerHTML = `
            <button id="rewind-btn" title="快退 ${skipSeconds}秒">⏪</button>
            <button id="play-pause-btn" class="pause" title="暂停">⏸️</button>
            <button id="forward-btn" title="快进 ${skipSeconds}秒">⏩</button>
            <button id="fullscreen-btn" class="fullscreen" title="横屏全屏">🔄</button>
            <input type="number" id="skip-input" value="${skipSeconds}" min="1" max="60" title="调整秒数">
            <span class="video-info" id="current-time">00:00</span>
        `;

        document.body.appendChild(controller);

        // 绑定事件
        const rewindBtn = document.getElementById('rewind-btn');
        const playPauseBtn = document.getElementById('play-pause-btn');
        const forwardBtn = document.getElementById('forward-btn');
        const fullscreenBtn = document.getElementById('fullscreen-btn');
        const skipInput = document.getElementById('skip-input');

        // 快退
        rewindBtn.addEventListener('click', () => {
            video.currentTime = Math.max(0, video.currentTime - skipSeconds);
        });

        // 播放/暂停
        playPauseBtn.addEventListener('click', () => {
            if (video.paused) {
                video.play();
                playPauseBtn.textContent = '⏸️';
                playPauseBtn.title = '暂停';
                playPauseBtn.classList.add('pause');
            } else {
                video.pause();
                playPauseBtn.textContent = '▶️';
                playPauseBtn.title = '播放';
                playPauseBtn.classList.remove('pause');
            }
        });

        // 快进
        forwardBtn.addEventListener('click', () => {
            video.currentTime = Math.min(video.duration, video.currentTime + skipSeconds);
        });

        // 横屏全屏
        fullscreenBtn.addEventListener('click', async () => {
            try {
                // 尝试进入全屏
                if (video.requestFullscreen) {
                    await video.requestFullscreen();
                } else if (video.webkitRequestFullscreen) {
                    await video.webkitRequestFullscreen();
                } else if (video.mozRequestFullScreen) {
                    await video.mozRequestFullScreen();
                } else if (video.msRequestFullscreen) {
                    await video.msRequestFullscreen();
                }

                // 尝试锁定屏幕方向为横屏
                if (screen.orientation && screen.orientation.lock) {
                    try {
                        await screen.orientation.lock('landscape');
                    } catch (err) {
                        console.log('无法锁定屏幕方向:', err);
                    }
                }
            } catch (err) {
                console.error('全屏失败:', err);
                alert('全屏失败,请手动旋转屏幕');
            }
        });

        // 修改秒数
        skipInput.addEventListener('change', (e) => {
            const value = parseInt(e.target.value);
            if (value > 0 && value <= 60) {
                skipSeconds = value;
                rewindBtn.title = `快退 ${skipSeconds}秒`;
                forwardBtn.title = `快进 ${skipSeconds}秒`;
            }
        });

        // 更新时间显示
        function formatTime(seconds) {
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        }

        video.addEventListener('timeupdate', () => {
            document.getElementById('current-time').textContent = formatTime(video.currentTime);
        });

        // 监听视频播放状态变化
        video.addEventListener('play', () => {
            playPauseBtn.textContent = '⏸️';
            playPauseBtn.title = '暂停';
            playPauseBtn.classList.add('pause');
        });

        video.addEventListener('pause', () => {
            playPauseBtn.textContent = '▶️';
            playPauseBtn.title = '播放';
            playPauseBtn.classList.remove('pause');
        });

        // 键盘快捷键
        document.addEventListener('keydown', (e) => {
            // 避免在输入框中触发
            if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
                return;
            }

            switch (e.key) {
                case 'ArrowLeft':
                    e.preventDefault();
                    video.currentTime = Math.max(0, video.currentTime - skipSeconds);
                    break;
                case 'ArrowRight':
                    e.preventDefault();
                    video.currentTime = Math.min(video.duration, video.currentTime + skipSeconds);
                    break;
                case ' ':
                    e.preventDefault();
                    if (video.paused) {
                        video.play();
                    } else {
                        video.pause();
                    }
                    break;
            }
        });
    }

    // 初始化
    function init() {
        const videos = findVideos();
        if (videos.length > 0) {
            // 默认控制第一个视频
            createController(videos[0]);
            console.log(`找到 ${videos.length} 个视频元素,已创建控制器`);
        }
    }

    // 页面加载完成后执行
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

    // 监听动态加载的视频
    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            if (mutation.addedNodes.length) {
                const videos = findVideos();
                if (videos.length > 0 && !document.getElementById('video-controller')) {
                    createController(videos[0]);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

})();