flyvideo

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

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==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
    });

})();