Greasy Fork

Greasy Fork is available in English.

Universal Video Share Button

Adds a floating share button that appears when videos are detected. Hold down to copy instead of share.

当前为 2025-11-04 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Universal Video Share Button
// @namespace    http://tampermonkey.net/
// @version      3.1
// @description  Adds a floating share button that appears when videos are detected. Hold down to copy instead of share.
// @author       Minoa
// @match        *://*/*
// @grant        none

// @license MIT

// ==/UserScript==

(function() {
    'use strict';

    var floatingButton = null;
    var pressTimer = null;
    var isLongPress = false;
    var checkInterval = null;

    // Common video selectors across different sites
    var VIDEO_SELECTORS = [
        'video',
        '.video-player video',
        '.player video',
        '#player video',
        '.video-container video',
        '[class*="video"] video',
        '[class*="player"] video',
        'iframe[src*="youtube.com"]',
        'iframe[src*="vimeo.com"]',
        'iframe[src*="dailymotion.com"]',
        'iframe[src*="twitch.tv"]',
        'iframe[src*="pornhub.com"]',
        'iframe[src*="xvideos.com"]'
    ];

    // Function to get video URL from various sources
    function getVideoUrl(videoElement) {
        if (videoElement.tagName === 'VIDEO') {
            if (videoElement.currentSrc) {
                return videoElement.currentSrc;
            }
            if (videoElement.src) {
                return videoElement.src;
            }
            
            var sources = videoElement.querySelectorAll('source');
            for (var i = 0; i < sources.length; i++) {
                if (sources[i].src) {
                    return sources[i].src;
                }
            }
        }

        if (videoElement.tagName === 'IFRAME') {
            return videoElement.src;
        }

        return window.location.href;
    }

    // Function to get unique videos
    function getUniqueVideos() {
        var videos = [];
        var seenUrls = [];
        
        for (var s = 0; s < VIDEO_SELECTORS.length; s++) {
            var selector = VIDEO_SELECTORS[s];
            var elements = document.querySelectorAll(selector);
            
            for (var i = 0; i < elements.length; i++) {
                var element = elements[i];
                var rect = element.getBoundingClientRect();
                
                if (rect.width > 100 && rect.height > 100) {
                    var url = getVideoUrl(element);
                    var isNewUrl = true;
                    
                    for (var j = 0; j < seenUrls.length; j++) {
                        if (seenUrls[j] === url) {
                            isNewUrl = false;
                            break;
                        }
                    }
                    
                    if (isNewUrl) {
                        seenUrls.push(url);
                        videos.push({
                            element: element,
                            url: url,
                            title: element.title || element.alt || ('Video ' + (videos.length + 1))
                        });
                    }
                }
            }
        }
        
        return videos;
    }

    // Function to create floating share button
    function createFloatingButton() {
        if (floatingButton) {
            return floatingButton;
        }

        floatingButton = document.createElement('div');
        floatingButton.innerHTML = '📤';
        floatingButton.id = 'universal-video-share-float';
        
        floatingButton.style.cssText = 'position: fixed; top: 20px; right: 20px; width: 50px; height: 50px; background: rgba(102, 126, 234, 0.9); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); color: white; border: 2px solid rgba(255, 255, 255, 0.2); border-radius: 50%; font-size: 18px; cursor: pointer; z-index: 999999; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; user-select: none; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);';

        // Hover effects
        floatingButton.addEventListener('mouseenter', function() {
            this.style.transform = 'scale(1.1)';
            this.style.background = 'rgba(102, 126, 234, 1)';
        });

        floatingButton.addEventListener('mouseleave', function() {
            this.style.transform = 'scale(1)';
            this.style.background = 'rgba(102, 126, 234, 0.9)';
        });

        // Handle mouse events for long press detection
        floatingButton.addEventListener('mousedown', function(e) {
            e.preventDefault();
            isLongPress = false;
            pressTimer = setTimeout(function() {
                isLongPress = true;
                floatingButton.style.background = 'rgba(46, 204, 113, 0.9)';
                floatingButton.innerHTML = '📋';
            }, 500);
        });

        floatingButton.addEventListener('mouseup', function(e) {
            e.preventDefault();
            clearTimeout(pressTimer);
            
            floatingButton.style.background = 'rgba(102, 126, 234, 0.9)';
            floatingButton.innerHTML = '📤';
            
            if (isLongPress) {
                handleCopy();
            } else {
                handleShare();
            }
        });

        floatingButton.addEventListener('mouseleave', function() {
            clearTimeout(pressTimer);
            floatingButton.style.background = 'rgba(102, 126, 234, 0.9)';
            floatingButton.innerHTML = '📤';
        });

        // Touch events for mobile
        floatingButton.addEventListener('touchstart', function(e) {
            e.preventDefault();
            isLongPress = false;
            pressTimer = setTimeout(function() {
                isLongPress = true;
                floatingButton.style.background = 'rgba(46, 204, 113, 0.9)';
                floatingButton.innerHTML = '📋';
            }, 500);
        });

        floatingButton.addEventListener('touchend', function(e) {
            e.preventDefault();
            clearTimeout(pressTimer);
            
            floatingButton.style.background = 'rgba(102, 126, 234, 0.9)';
            floatingButton.innerHTML = '📤';
            
            if (isLongPress) {
                handleCopy();
            } else {
                handleShare();
            }
        });

        document.body.appendChild(floatingButton);
        return floatingButton;
    }

    // Function to handle share action
    function handleShare() {
        var videos = getUniqueVideos();
        
        if (videos.length === 0) {
            showNotification('No videos found!', 'error');
            return;
        }
        
        if (videos.length === 1) {
            shareVideo(videos[0]);
        } else {
            showVideoSelector(videos, 'share');
        }
    }

    // Function to handle copy action
    function handleCopy() {
        var videos = getUniqueVideos();
        
        if (videos.length === 0) {
            showNotification('No videos found!', 'error');
            return;
        }
        
        if (videos.length === 1) {
            copyVideoUrl(videos[0]);
        } else {
            showVideoSelector(videos, 'copy');
        }
    }

    // Function to create video selector popup
    function showVideoSelector(videos, action) {
        // Remove existing selector if any
        var existingSelector = document.querySelector('#video-selector-popup');
        if (existingSelector) {
            existingSelector.remove();
        }

        var popup = document.createElement('div');
        popup.id = 'video-selector-popup';
        popup.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); z-index: 9999999; display: flex; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box;';

        var container = document.createElement('div');
        container.style.cssText = 'background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-radius: 15px; padding: 30px; max-width: 80%; max-height: 80%; overflow-y: auto; position: relative; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);';

        // Close button
        var closeButton = document.createElement('button');
        closeButton.innerHTML = '✕';
        closeButton.style.cssText = 'position: absolute; top: 15px; right: 15px; background: none; border: none; font-size: 20px; cursor: pointer; color: #666; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;';

        closeButton.addEventListener('click', function() {
            popup.remove();
        });
        
        closeButton.addEventListener('mouseenter', function() {
            this.style.background = 'rgba(0, 0, 0, 0.1)';
        });
        
        closeButton.addEventListener('mouseleave', function() {
            this.style.background = 'none';
        });

        // Title
        var title = document.createElement('h3');
        title.textContent = 'Select Video to ' + (action.charAt(0).toUpperCase() + action.slice(1));
        title.style.cssText = 'margin: 0 0 20px 0; color: #333; font-size: 18px; text-align: center;';

        container.appendChild(closeButton);
        container.appendChild(title);

        // Video list
        for (var i = 0; i < videos.length; i++) {
            var videoData = videos[i];
            var videoItem = document.createElement('div');
            videoItem.style.cssText = 'margin-bottom: 20px; padding: 15px; border: 2px solid #ddd; border-radius: 10px; cursor: pointer; transition: all 0.3s ease; background: rgba(255, 255, 255, 0.7);';

            // Create a closure to capture the current videoData
            (function(currentVideoData) {
                videoItem.addEventListener('mouseenter', function() {
                    this.style.borderColor = '#667eea';
                    this.style.background = 'rgba(102, 126, 234, 0.1)';
                });

                videoItem.addEventListener('mouseleave', function() {
                    this.style.borderColor = '#ddd';
                    this.style.background = 'rgba(255, 255, 255, 0.7)';
                });

                // Create preview video element
                if (currentVideoData.element.tagName === 'VIDEO') {
                    var previewVideo = document.createElement('video');
                    previewVideo.src = currentVideoData.url;
                    previewVideo.style.cssText = 'width: 100%; max-width: 300px; height: auto; border-radius: 5px; margin-bottom: 10px;';
                    previewVideo.controls = false;
                    previewVideo.muted = true;
                    previewVideo.preload = 'metadata';
                    videoItem.appendChild(previewVideo);
                } else {
                    // For iframes, show a placeholder
                    var placeholder = document.createElement('div');
                    placeholder.style.cssText = 'width: 100%; max-width: 300px; height: 150px; background: #f0f0f0; border-radius: 5px; margin-bottom: 10px; display: flex; align-items: center; justify-content: center; color: #666; font-size: 14px;';
                    placeholder.textContent = 'Embedded Video';
                    videoItem.appendChild(placeholder);
                }

                // Video info
                var videoInfo = document.createElement('div');
                videoInfo.innerHTML = '<strong>Video ' + (i + 1) + '</strong><br><small style="color: #666; word-break: break-all;">' + currentVideoData.url + '</small>';
                videoItem.appendChild(videoInfo);

                // Click handler
                videoItem.addEventListener('click', function() {
                    popup.remove();
                    if (action === 'share') {
                        shareVideo(currentVideoData);
                    } else {
                        copyVideoUrl(currentVideoData);
                    }
                });
            })(videoData);

            container.appendChild(videoItem);
        }

        popup.appendChild(container);

        // Click outside to close
        popup.addEventListener('click', function(e) {
            if (e.target === popup) {
                popup.remove();
            }
        });

        document.body.appendChild(popup);
    }

    // Function to share video
    function shareVideo(videoData) {
        var pageTitle = document.title;

        if (navigator.share) {
            navigator.share({
                title: pageTitle,

                url: videoData.url
            }).then(function() {
                showNotification('Video shared successfully!', 'success');
            }).catch(function(error) {
                console.log('Error sharing video:', error);
                copyVideoUrl(videoData);
            });
        } else {
            copyVideoUrl(videoData);
        }
    }

    // Function to copy video URL
    function copyVideoUrl(videoData) {
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(videoData.url).then(function() {
                showNotification('Video URL copied to clipboard!', 'success');
            }).catch(function() {
                fallbackCopy(videoData.url);
            });
        } else {
            fallbackCopy(videoData.url);
        }
    }

    // Fallback copy method
    function fallbackCopy(url) {
        try {
            var textArea = document.createElement('textarea');
            textArea.value = url;
            textArea.style.position = 'fixed';
            textArea.style.left = '-999999px';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            
            if (document.execCommand('copy')) {
                showNotification('Video URL copied to clipboard!', 'success');
            } else {
                showNotification('Could not copy URL', 'error');
            }
            
            document.body.removeChild(textArea);
        } catch (err) {
            showNotification('Copy failed', 'error');
        }
    }

    // Function to show notification
    function showNotification(message, type) {
        if (type === undefined) {
            type = 'success';
        }
        
        var existingNotifications = document.querySelectorAll('.universal-video-notification');
        for (var i = 0; i < existingNotifications.length; i++) {
            existingNotifications[i].remove();
        }

        var notification = document.createElement('div');
        notification.textContent = message;
        notification.className = 'universal-video-notification';
        
        var bgColor = type === 'success' ? 'rgba(46, 204, 113, 0.95)' : 'rgba(231, 76, 60, 0.95)';
        
        notification.style.cssText = 'position: fixed; top: 80px; right: 20px; background: ' + bgColor + '; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); color: white; padding: 12px 20px; border-radius: 10px; z-index: 999998; font-weight: 600; font-size: 14px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); max-width: 300px; word-wrap: break-word; transform: translateX(100%); transition: transform 0.3s ease;';

        document.body.appendChild(notification);
        
        // Animate in
        setTimeout(function() {
            notification.style.transform = 'translateX(0)';
        }, 100);

        // Remove after 3 seconds
        setTimeout(function() {
            if (notification.parentNode) {
                notification.style.transform = 'translateX(100%)';
                setTimeout(function() {
                    notification.remove();
                }, 300);
            }
        }, 3000);
    }

    // Function to check for videos and show/hide button
    function checkForVideos() {
        var videos = getUniqueVideos();
        
        if (videos.length > 0) {
            if (!floatingButton) {
                createFloatingButton();
            }
        } else {
            if (floatingButton) {
                floatingButton.remove();
                floatingButton = null;
            }
        }
    }

    // Initialize the script
    function init() {
        console.log('Universal Video Share Button script initialized');
        
        // Check immediately
        setTimeout(checkForVideos, 1000);
        
        // Set up interval to check every 5 seconds
        checkInterval = setInterval(checkForVideos, 5000);
    }

    // Start the script
    init();

})();