旋转bilibili视频增加一个旋转按Rotate Bilibili player with a button

bilibili视频增加一个旋转按钮,特别针对Edge浏览器优化 Rotate Bilibili player with a button, Optimized for the Edge browser.

// ==UserScript==
// @name         旋转bilibili视频增加一个旋转按Rotate Bilibili player with a button
// @name:en      Rotate Bilibili player with a button, Optimized for the Edge browser
// @namespace    Alright Peaches Studio
// @version      0.3
// @description  bilibili视频增加一个旋转按钮,特别针对Edge浏览器优化 Rotate Bilibili player with a button, Optimized for the Edge browser.
// @description:en  Rotate Bilibili player with a button, Optimized for the Edge browser.
// @description[zh-CN] bilibili视频增加一个旋转按钮,特别针对Edge浏览器优化 Rotate Bilibili player with a button, Optimized for the Edge browser.
// @author       Alright Peaches Studio
// @license      MIT
// @match        https://www.bilibili.com/video/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 候选容器列表(按优先级排序)
    const CONTAINER_SELECTORS = [
        '.bpx-player-control-bottom-center', // 底部控制栏中间
        '.bpx-player-control-bottom-right', // 底部控制栏右侧
        '.bpx-player-top-right',            // 顶部右侧信息区
        '.bpx-player-top-left',              // 经典位置(原位置)
        '.bpx-player-video-area',            // 直接插入视频区域
        '.bpx-player-container'              // 最后兜底
    ];

    // 创建按钮元素
    const createRotateButton = () => {
        const btn = document.createElement("button");
        btn.innerHTML = "旋转Rotate";
        btn.id = "bili-rotate-btn";

        // 增强版样式
        Object.assign(btn.style, {
            width: "80px",
            height: "32px",
            backgroundColor: "#00aeec",
            border: "1px solid rgba(255,255,255,0.2)",
            color: "#fff",
            fontSize: "14px",
            borderRadius: "16px",
            transition: "all 0.2s",
            cursor: "pointer",
            position: "relative",
            zIndex: "2147483647", // 最大z-index值
            boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
            margin: "0 8px",
            flexShrink: "0"
        });

        // 悬停效果
        btn.addEventListener("mouseover", () => {
            btn.style.backgroundColor = "#0099cc";
            btn.style.boxShadow = "0 3px 6px rgba(0,0,0,0.3)";
        });

        btn.addEventListener("mouseout", () => {
            btn.style.backgroundColor = "#00aeec";
            btn.style.boxShadow = "0 2px 4px rgba(0,0,0,0.2)";
        });

        return btn;
    };

    // 查找可用容器
    const findValidContainer = () => {
        for (const selector of CONTAINER_SELECTORS) {
            const container = document.querySelector(selector);
            if (container) {
                // 检查容器是否可见
                const style = window.getComputedStyle(container);
                if (style.display !== 'none' && style.visibility === 'visible') {
                    return container;
                }
            }
        }
        return null;
    };

    // 旋转逻辑
    const rotateVideo = () => {
        const video = document.querySelector('video');
        if (!video) return;

        const currentRotate = parseInt(video.dataset.rotate) || 0;
        const newRotate = (currentRotate + 90) % 360;
        video.dataset.rotate = newRotate;

        // 应用变换
        video.style.transform = `rotate(${newRotate}deg)`;
        video.style.transformOrigin = 'center center';

        // 自动调整容器尺寸
        const container = video.closest('.bpx-player-video-wrap');
        if (container) {
            container.style.transform = newRotate % 180 === 0
                ? 'scale(1)'
                : 'scale(0.5626)';
        }
    };

    // 主执行逻辑
    const init = () => {
        // 防止重复注入
        if (document.getElementById('bili-rotate-btn')) return;

        const container = findValidContainer();
        if (!container) {
            console.warn('[旋转按钮] 未找到有效容器');
            return;
        }

        const btn = createRotateButton();
        btn.onclick = rotateVideo;

        // 智能插入策略
        if (container.classList.contains('bpx-player-control-bottom-center')) {
            // 插入到播放进度条前
            const progress = container.querySelector('.bpx-player-progress');
            if (progress) {
                container.insertBefore(btn, progress);
            } else {
                container.prepend(btn);
            }
        } else {
            // 其他容器直接追加
            container.append(btn);
        }

        // 强制显示按钮
        btn.style.display = 'block !important';
        btn.style.visibility = 'visible !important';
    };

    // 增强版监听方案
    const observer = new MutationObserver(mutations => {
        if (!document.getElementById('bili-rotate-btn')) {
            init();
        }
    });

    // 启动监听
    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: false,
        characterData: false
    });

    // 初始执行
    if (document.readyState === 'complete') {
        init();
    } else {
        window.addEventListener('load', init);
        document.addEventListener('DOMContentLoaded', init);
    }
})();
长期地址
遇到问题?请前往 GitHub 提 Issues,或加Q群1031348184

赞助商

Fishcpy

广告

Rainyun

注册一下就行

Rainyun

一年攒够 12 元