Greasy Fork

Greasy Fork is available in English.

Sora2 去水印-大洋芋去水印dyysy.com

在Sora视频详情页的菜单中,于“Download”按钮旁增加一个“大洋芋-去水印下载”按钮。

// ==UserScript==
// @license      MIT
// @name         Sora2 去水印-大洋芋去水印dyysy.com
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  在Sora视频详情页的菜单中,于“Download”按钮旁增加一个“大洋芋-去水印下载”按钮。
// @author       CodeBuddy
// @match        https://sora.chatgpt.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==


(function() {
    'use strict';

    console.log('[Sor2 去水印 - 去水印] 脚本已启动。');

    /**
     * 防抖函数,防止函数因DOM频繁变动而被高频触发,提升性能。
     * @param {Function} func 要执行的函数
     * @param {number} wait 延迟时间(毫秒)
     * @returns {Function}
     */
    function debounce(func, wait) {
        let timeout;
        return function(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    /**
     * 查找 "Download" 按钮并添加去水印下载按钮。
     */
    function addNoWatermarkButton() {
        // 脚本只在视频详情页(URL中包含 /p/)生效
        if (!window.location.href.includes('/p/')) {
            return;
        }

        const downloadButtonText = 'Download';

        // 查找页面上所有的菜单项
        document.querySelectorAll('[role="menuitem"]').forEach(buttonElement => {
            // 检查文本内容是否为 "Download"
            if (buttonElement.textContent.trim() === downloadButtonText) {
                const parent = buttonElement.parentNode;

                // 确保父节点存在,并且我们的自定义按钮尚未添加
                if (parent && !parent.querySelector('.sora-helper-no-watermark-btn')) {
                    console.log('[Sora Helper - 去水印] 找到 "Download" 按钮,正在添加新按钮...');

                    // 创建一个新 div 元素作为我们的按钮
                    const newButton = document.createElement('div');

                    // 复制原按钮的 class 以保持样式一致,并添加一个唯一标识 class
                    newButton.className = buttonElement.className + ' sora-helper-no-watermark-btn';
                    newButton.setAttribute('role', 'menuitem');

                    // 使用原按钮的 innerHTML 结构,只替换文本内容
                    newButton.innerHTML = buttonElement.innerHTML.replace(downloadButtonText, '大洋芋-去水印下载');

                    // 添加点击事件
                    newButton.addEventListener('click', (e) => {
                        e.preventDefault();  // 阻止默认事件
                        e.stopPropagation(); // 阻止事件冒泡,防止关闭菜单

                        // 在新标签页中打开去水印解析网站
                        window.open(`https://dyysy.com/?url=${encodeURIComponent(window.location.href)}`, '_blank');
                    });

                    // 将新按钮插入到原 "Download" 按钮之后
                    parent.insertBefore(newButton, buttonElement.nextSibling);
                    console.log('[Sora Helper - 去水印] “大洋芋-去水印下载”按钮已成功添加。');
                }
            }
        });
    }

    // 创建一个 MutationObserver 来监听DOM的变化。
    // 这对于像Sora这样的单页应用(SPA)至关重要,因为菜单是动态加载的。
    const observer = new MutationObserver(debounce(addNoWatermarkButton, 500));

    // 配置观察者:观察 body 元素下的所有后代节点的增删
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    // 在脚本加载后,立即尝试执行一次,以应对页面已加载完成的情况
    addNoWatermarkButton();

})();