| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>AI Video Generator Pro - Demo Mode</title> |
| <style> |
| * { |
| margin: 0; |
| padding: 0; |
| box-sizing: border-box; |
| } |
| |
| body { |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| min-height: 100vh; |
| padding: 20px; |
| } |
| |
| .container { |
| max-width: 1200px; |
| margin: 0 auto; |
| background: white; |
| border-radius: 20px; |
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); |
| overflow: hidden; |
| } |
| |
| .header { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| color: white; |
| padding: 30px 40px; |
| text-align: center; |
| } |
| |
| .header h1 { |
| font-size: 32px; |
| margin-bottom: 10px; |
| } |
| |
| .header p { |
| font-size: 16px; |
| opacity: 0.9; |
| } |
| |
| .demo-notice { |
| background: #fff3cd; |
| color: #856404; |
| padding: 15px; |
| text-align: center; |
| border-bottom: 2px solid #ffc107; |
| font-weight: 500; |
| } |
| |
| .main-content { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: 30px; |
| padding: 40px; |
| } |
| |
| .section { |
| background: #f8f9fa; |
| padding: 20px; |
| border-radius: 12px; |
| } |
| |
| .section h3 { |
| color: #333; |
| margin-bottom: 15px; |
| font-size: 18px; |
| } |
| |
| label { |
| display: block; |
| color: #555; |
| margin-bottom: 8px; |
| font-weight: 500; |
| font-size: 14px; |
| } |
| |
| textarea, select { |
| width: 100%; |
| padding: 12px; |
| border: 2px solid #e0e0e0; |
| border-radius: 8px; |
| font-size: 14px; |
| font-family: inherit; |
| transition: border-color 0.3s; |
| } |
| |
| textarea { |
| resize: vertical; |
| min-height: 100px; |
| } |
| |
| textarea:focus, select:focus { |
| outline: none; |
| border-color: #667eea; |
| } |
| |
| .options-grid { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: 15px; |
| margin-top: 15px; |
| } |
| |
| button { |
| width: 100%; |
| padding: 16px; |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| color: white; |
| border: none; |
| border-radius: 10px; |
| font-size: 18px; |
| font-weight: 600; |
| cursor: pointer; |
| transition: transform 0.2s, box-shadow 0.2s; |
| margin-top: 20px; |
| } |
| |
| button:hover:not(:disabled) { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); |
| } |
| |
| button:disabled { |
| opacity: 0.6; |
| cursor: not-allowed; |
| } |
| |
| .loader { |
| border: 3px solid #f3f3f3; |
| border-top: 3px solid #667eea; |
| border-radius: 50%; |
| width: 40px; |
| height: 40px; |
| animation: spin 1s linear infinite; |
| margin: 20px auto; |
| display: none; |
| } |
| |
| @keyframes spin { |
| 0% { transform: rotate(0deg); } |
| 100% { transform: rotate(360deg); } |
| } |
| |
| .status { |
| padding: 12px; |
| border-radius: 8px; |
| text-align: center; |
| font-size: 14px; |
| display: none; |
| margin-top: 15px; |
| } |
| |
| .status.info { |
| background: #e3f2fd; |
| color: #1976d2; |
| display: block; |
| } |
| |
| .status.success { |
| background: #e8f5e9; |
| color: #388e3c; |
| display: block; |
| } |
| |
| .status.error { |
| background: #ffebee; |
| color: #d32f2f; |
| display: block; |
| } |
| |
| .video-container { |
| background: #000; |
| border-radius: 12px; |
| overflow: hidden; |
| display: none; |
| margin-top: 15px; |
| } |
| |
| video { |
| width: 100%; |
| display: block; |
| } |
| |
| .video-info { |
| background: #f8f9fa; |
| padding: 15px; |
| margin-top: 10px; |
| border-radius: 8px; |
| font-size: 13px; |
| color: #666; |
| } |
| |
| .example-prompts { |
| margin-top: 15px; |
| } |
| |
| .example-prompt { |
| display: inline-block; |
| padding: 8px 16px; |
| margin: 4px; |
| background: white; |
| border: 2px solid #667eea; |
| border-radius: 20px; |
| font-size: 13px; |
| cursor: pointer; |
| transition: all 0.2s; |
| color: #667eea; |
| font-weight: 500; |
| } |
| |
| .example-prompt:hover { |
| background: #667eea; |
| color: white; |
| } |
| |
| .features-list { |
| list-style: none; |
| margin-top: 15px; |
| } |
| |
| .features-list li { |
| padding: 8px 0; |
| color: #555; |
| } |
| |
| .features-list li:before { |
| content: "✓ "; |
| color: #667eea; |
| font-weight: bold; |
| margin-right: 8px; |
| } |
| |
| @media (max-width: 768px) { |
| .main-content { |
| grid-template-columns: 1fr; |
| } |
| .options-grid { |
| grid-template-columns: 1fr; |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="header"> |
| <h1>🎬 AI Video Generator Pro</h1> |
| <p>Hailuo-Inspired Features with Multiple AI Models</p> |
| </div> |
|
|
| <div class="demo-notice"> |
| ⚠️ DEMO MODE: This demo uses a sample video to showcase the UI. Real video generation requires Hugging Face Space connections. |
| </div> |
|
|
| <div class="main-content"> |
| |
| <div> |
| <div class="section"> |
| <h3>📝 Enter Your Prompt</h3> |
| <label for="prompt">Describe the video you want to create:</label> |
| <textarea |
| id="prompt" |
| rows="4" |
| placeholder="e.g., A golden retriever running through a field of sunflowers at sunset" |
| >A golden retriever running through a field of flowers</textarea> |
| </div> |
|
|
| <div class="section"> |
| <h3>🎥 Advanced Options (Hailuo-Inspired)</h3> |
| <div class="options-grid"> |
| <div> |
| <label for="camera">Camera Movement:</label> |
| <select id="camera"> |
| <option value="">Static</option> |
| <option value="[Zoom in]">Zoom In</option> |
| <option value="[Zoom out]">Zoom Out</option> |
| <option value="[Pan left]">Pan Left</option> |
| <option value="[Pan right]">Pan Right</option> |
| <option value="[Tracking shot]" selected>Tracking Shot</option> |
| <option value="[Dolly in]">Dolly In</option> |
| </select> |
| </div> |
| <div> |
| <label for="effect">Visual Effect:</label> |
| <select id="effect"> |
| <option value="">None</option> |
| <option value="cinematic lighting, film grain" selected>Cinematic</option> |
| <option value="dramatic lighting, high contrast">Dramatic</option> |
| <option value="golden hour, warm sunset lighting">Golden Hour</option> |
| <option value="fog, misty atmosphere">Foggy</option> |
| </select> |
| </div> |
| </div> |
| <div style="margin-top: 15px;"> |
| <label for="style">Video Style:</label> |
| <select id="style"> |
| <option value="">Default</option> |
| <option value="photorealistic, 4k, high detail" selected>Realistic</option> |
| <option value="anime style, animated">Anime</option> |
| <option value="3D render, CGI, Pixar style">3D Render</option> |
| <option value="cinematic, movie scene">Cinematic</option> |
| </select> |
| </div> |
| </div> |
|
|
| <button onclick="generateVideo()">🎬 Generate Video (Demo)</button> |
| </div> |
|
|
| |
| <div> |
| <div class="section"> |
| <h3>🎞️ Generated Video</h3> |
| <div class="loader" id="loader"></div> |
| <div class="status" id="status"></div> |
| |
| <div class="video-container" id="video-container"> |
| <video id="video-output" controls></video> |
| </div> |
|
|
| <div id="video-info" class="video-info" style="display: none;"></div> |
| </div> |
|
|
| <div class="section"> |
| <h3>💡 Example Prompts</h3> |
| <div class="example-prompts"> |
| <span class="example-prompt" onclick="setPrompt('A golden retriever running through a field of flowers')">🐕 Dog in field</span> |
| <span class="example-prompt" onclick="setPrompt('Ocean waves crashing on a beach at sunset')">🌊 Ocean sunset</span> |
| <span class="example-prompt" onclick="setPrompt('A sports car drifting around a corner')">🏎️ Racing car</span> |
| <span class="example-prompt" onclick="setPrompt('A dragon flying over a medieval castle')">🐉 Fantasy dragon</span> |
| </div> |
| </div> |
|
|
| <div class="section"> |
| <h3>✨ Features</h3> |
| <ul class="features-list"> |
| <li>5 AI Models (CogVideoX, LTX, SVD, AnimateDiff, Zeroscope)</li> |
| <li>Text-to-Video & Image-to-Video</li> |
| <li>12 Camera Movements (Hailuo-style)</li> |
| <li>8 Visual Effects</li> |
| <li>8 Video Styles</li> |
| <li>Enhanced Prompt Building</li> |
| <li>Professional UI Design</li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| let currentVideoUrl = null; |
| |
| function setPrompt(text) { |
| document.getElementById('prompt').value = text; |
| } |
| |
| function showStatus(message, type) { |
| const status = document.getElementById('status'); |
| status.textContent = message; |
| status.className = 'status ' + type; |
| } |
| |
| async function generateVideo() { |
| const prompt = document.getElementById('prompt').value.trim(); |
| const camera = document.getElementById('camera').value; |
| const effect = document.getElementById('effect').value; |
| const style = document.getElementById('style').value; |
| |
| if (!prompt) { |
| showStatus('Please enter a prompt', 'error'); |
| return; |
| } |
| |
| |
| let enhancedPrompt = prompt; |
| if (style) enhancedPrompt = style + ', ' + enhancedPrompt; |
| if (camera) enhancedPrompt += ' ' + camera; |
| if (effect) enhancedPrompt += ', ' + effect; |
| |
| |
| const btn = document.querySelector('button'); |
| btn.disabled = true; |
| btn.textContent = '🎬 Generating...'; |
| document.getElementById('loader').style.display = 'block'; |
| document.getElementById('video-container').style.display = 'none'; |
| document.getElementById('video-info').style.display = 'none'; |
| showStatus('🎨 Generating your video... (Demo mode - instant)', 'info'); |
| |
| try { |
| |
| await new Promise(resolve => setTimeout(resolve, 2000)); |
| |
| const response = await fetch('http://localhost:5000/test-video', { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify({ prompt: enhancedPrompt }) |
| }); |
| |
| const data = await response.json(); |
| |
| if (!response.ok || data.error) { |
| throw new Error(data.error || 'Failed to generate video'); |
| } |
| |
| |
| currentVideoUrl = data.video_url; |
| const videoOutput = document.getElementById('video-output'); |
| videoOutput.src = currentVideoUrl; |
| document.getElementById('video-container').style.display = 'block'; |
| |
| |
| const videoInfo = document.getElementById('video-info'); |
| videoInfo.innerHTML = ` |
| <strong>Mode:</strong> ${data.model_name}<br> |
| <strong>Your Prompt:</strong> ${prompt}<br> |
| <strong>Enhanced Prompt:</strong> ${data.enhanced_prompt}<br> |
| <strong>Note:</strong> ${data.note} |
| `; |
| videoInfo.style.display = 'block'; |
| |
| showStatus('✅ Demo video loaded! This showcases the UI. Connect to HF Spaces for real generation.', 'success'); |
| videoOutput.play().catch(() => {}); |
| |
| } catch (error) { |
| console.error('Error:', error); |
| showStatus('❌ Error: ' + error.message, 'error'); |
| } finally { |
| btn.disabled = false; |
| btn.textContent = '🎬 Generate Video (Demo)'; |
| document.getElementById('loader').style.display = 'none'; |
| } |
| } |
| |
| |
| window.addEventListener('load', async () => { |
| try { |
| const response = await fetch('http://localhost:5000/health'); |
| const data = await response.json(); |
| if (data.status === 'healthy') { |
| console.log('✅ Server is healthy'); |
| showStatus('✅ Server connected! Try the demo by clicking Generate Video', 'success'); |
| } |
| } catch (error) { |
| showStatus('⚠️ Cannot connect to server. Make sure backend is running on port 5000', 'error'); |
| } |
| }); |
| </script> |
| </body> |
| </html> |
|
|