您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhance your Sora video prompts with AI
// ==UserScript== // @name Sora Prompt Enhancer by robomonkey.io // @description Enhance your Sora video prompts with AI // @version 1.0.1 // @match https://*.sora.chatgpt.com/* // @icon https://cdn.openai.com/sora/assets/favicon-nf2.ico // @license MIT // @namespace https://greasyfork.org/users/1521443 // ==/UserScript== (function() { 'use strict'; console.log('Sora Prompt Enhancer loaded'); function addEnhanceButton() { // Check if button already exists if (document.getElementById('enhance-prompt-btn')) { console.log('Enhance button already exists'); return; } // Find the textarea const textarea = document.querySelector('textarea[placeholder*="Describe your video"]'); if (!textarea) { console.log('Textarea not found, will retry...'); return; } console.log('Textarea found, adding enhance button'); // Find the composer container (the parent with buttons) const composerContainer = textarea.closest('.flex.flex-col.gap-1\\.5'); if (!composerContainer) { console.log('Composer container not found'); return; } // Find the button row const buttonRow = composerContainer.querySelector('.flex.items-center.justify-between'); if (!buttonRow) { console.log('Button row not found'); return; } // Find the right side button group const rightButtonGroup = buttonRow.querySelector('.flex.gap-1\\.5:last-child'); if (!rightButtonGroup) { console.log('Right button group not found'); return; } // Create the enhance button const enhanceBtn = document.createElement('button'); enhanceBtn.id = 'enhance-prompt-btn'; enhanceBtn.className = 'inline-flex gap-1.5 items-center justify-center whitespace-nowrap text-sm font-semibold focus-visible:outline-none bg-token-bg-composer-button hover:bg-token-bg-active px-3 h-[36px] rounded-full'; enhanceBtn.innerHTML = '✨ Enhance'; enhanceBtn.style.cssText = 'background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; font-weight: 600; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);'; // Add hover effect enhanceBtn.addEventListener('mouseenter', () => { enhanceBtn.style.transform = 'scale(1.05)'; enhanceBtn.style.boxShadow = '0 4px 12px rgba(102, 126, 234, 0.5)'; }); enhanceBtn.addEventListener('mouseleave', () => { enhanceBtn.style.transform = 'scale(1)'; enhanceBtn.style.boxShadow = '0 2px 8px rgba(102, 126, 234, 0.3)'; }); // Add click handler enhanceBtn.addEventListener('click', async (e) => { e.preventDefault(); e.stopPropagation(); await enhancePrompt(textarea, enhanceBtn); }); // Insert the button before the settings button const settingsBtn = rightButtonGroup.querySelector('button[aria-label="Settings"]'); if (settingsBtn) { rightButtonGroup.insertBefore(enhanceBtn, settingsBtn); } else { rightButtonGroup.appendChild(enhanceBtn); } console.log('Enhance button added successfully'); } async function enhancePrompt(textarea, button) { const currentPrompt = textarea.value.trim(); if (!currentPrompt) { showNotification('Please enter a prompt first!', 'warning'); return; } // Save original button state const originalText = button.innerHTML; button.disabled = true; button.innerHTML = '⏳ Enhancing...'; button.style.opacity = '0.7'; try { console.log('Enhancing prompt:', currentPrompt); const enhancedPrompt = await RM.aiCall( `You are an expert at writing video generation prompts for Sora AI. Enhance the following prompt to be more detailed, cinematic, and effective for video generation. Include specific details about camera movements, lighting, mood, and visual style. Keep it concise but impactful (max 200 words). Original prompt: "${currentPrompt}" Provide ONLY the enhanced prompt, nothing else.`, { type: "json_schema", json_schema: { name: "enhanced_prompt", schema: { type: "object", properties: { enhancedPrompt: { type: "string", description: "The enhanced video generation prompt" }, improvements: { type: "array", items: { type: "string" }, description: "List of key improvements made" } }, required: ["enhancedPrompt"] } } } ); console.log('Enhanced prompt received:', enhancedPrompt); // Update the textarea with enhanced prompt textarea.value = enhancedPrompt.enhancedPrompt; // Trigger input event so Sora recognizes the change textarea.dispatchEvent(new Event('input', { bubbles: true })); textarea.dispatchEvent(new Event('change', { bubbles: true })); showNotification('Prompt enhanced successfully! ✨', 'success'); } catch (error) { console.error('Error enhancing prompt:', error); showNotification('Failed to enhance prompt. Please try again.', 'error'); } finally { // Restore button state button.disabled = false; button.innerHTML = originalText; button.style.opacity = '1'; } } function showNotification(message, type = 'info') { // Remove existing notification const existing = document.getElementById('enhance-notification'); if (existing) { existing.remove(); } const notification = document.createElement('div'); notification.id = 'enhance-notification'; const bgColors = { success: '#10b981', error: '#ef4444', warning: '#f59e0b', info: '#3b82f6' }; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: ${bgColors[type]}; color: white; padding: 16px 24px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 10000; font-size: 14px; font-weight: 500; animation: slideIn 0.3s ease-out; `; notification.textContent = message; document.body.appendChild(notification); // Add animation const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(400px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } `; document.head.appendChild(style); // Auto remove after 3 seconds setTimeout(() => { notification.style.animation = 'slideIn 0.3s ease-out reverse'; setTimeout(() => notification.remove(), 300); }, 3000); } function init() { console.log('Initializing Sora Prompt Enhancer'); // Try to add button immediately addEnhanceButton(); // Watch for DOM changes to add button when textarea appears const observer = new MutationObserver(() => { addEnhanceButton(); }); observer.observe(document.body, { childList: true, subtree: true }); console.log('Observer started'); } // Start when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();