Additional-Miniplayer

✨This is a script that allows all videos on Chrome to have Miniplayer functionality✨

// ==UserScript==
// @name         Additional-Miniplayer
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  ✨This is a script that allows all videos on Chrome to have Miniplayer functionality✨
// @author       Cherry Fu
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let buttonCounter = 0;

    // Function to add miniplayer button to a video element
    function addMiniplayerButton(video) {
        // Check if button already exists for this video
        if (video.hasAttribute('data-miniplayer-added')) return;
        video.setAttribute('data-miniplayer-added', 'true');

        console.log('Adding miniplayer button to video:', video);

        // Create button element
        const button = document.createElement('button');
        button.className = 'miniplayer-btn';
        button.setAttribute('data-video-id', ++buttonCounter);
        button.innerHTML = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect x="2" y="2" width="10" height="8" rx="1" ry="1" fill="white" stroke="black" stroke-width="1.5"/>
            <rect x="6" y="6" width="8" height="6" rx="1" ry="1" fill="white" stroke="black" stroke-width="1.5"/>
        </svg>`; // Miniplayer icon with overlapping rectangles
        button.style.cssText = `
            position: fixed;
            z-index: 1000000;
            background: white;
            border: 1px solid #ccc;
            border-radius: 3px;
            width: 24px;
            height: 24px;
            cursor: pointer;
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0.7;
            pointer-events: auto;
        `;

        // Function to update button position
        function updatePosition() {
            if (!video.isConnected) {
                button.remove();
                return;
            }
            // Find the appropriate container for positioning
            let container = video.closest('#movie_player') || video.closest('#player') || video.closest('.html5-video-player') || video.parentNode;
            const rect = container.getBoundingClientRect();
            if (rect.width > 0 && rect.height > 0) {
                button.style.left = (rect.left + 5) + 'px';
                button.style.top = (rect.top + 5) + 'px';
                button.style.display = 'flex';
            } else {
                button.style.display = 'none';
            }
        }

        // Initial position
        updatePosition();

        // Update position on scroll and resize
        window.addEventListener('scroll', updatePosition);
        window.addEventListener('resize', updatePosition);

        // Also update on video events
        video.addEventListener('loadedmetadata', updatePosition);
        video.addEventListener('play', updatePosition);

        // Add click event
        button.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            if (document.pictureInPictureElement) {
                document.exitPictureInPicture();
            } else if (video.requestPictureInPicture) {
                video.requestPictureInPicture().catch(console.error);
            }
        });

        // Add to body
        document.body.appendChild(button);
    }

    // Function to process all videos on the page
    function processVideos() {
        const videos = document.querySelectorAll('video');
        videos.forEach(addMiniplayerButton);
    }

    // Initial processing
    processVideos();

    // Delayed processing for dynamic content
    setTimeout(processVideos, 2000);
    setTimeout(processVideos, 5000);

    // Observe for new videos
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            mutation.addedNodes.forEach(function(node) {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    if (node.tagName === 'VIDEO') {
                        addMiniplayerButton(node);
                    } else {
                        const videos = node.querySelectorAll('video');
                        videos.forEach(addMiniplayerButton);
                    }
                }
            });
        });
    });

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