Spaces:
Sleeping
Sleeping
Pravin Barapatre
Pin dependencies for Hugging Face Spaces compatibility and remove submodule issue
db8251f | import gradio as gr | |
| import logging | |
| import tempfile | |
| import os | |
| # Set up logging | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| class TextToVideoGenerator: | |
| def __init__(self): | |
| self.device = "cpu" # Simplified for testing | |
| # Available models - including the advanced Wan2.1 model | |
| self.models = { | |
| "damo-vilab/text-to-video-ms-1.7b": { | |
| "name": "DAMO Text-to-Video MS-1.7B", | |
| "description": "Fast and efficient text-to-video model", | |
| "max_frames": 16, | |
| "fps": 8, | |
| "quality": "Good", | |
| "speed": "Fast" | |
| }, | |
| "cerspense/zeroscope_v2_XL": { | |
| "name": "Zeroscope v2 XL", | |
| "description": "High-quality text-to-video model", | |
| "max_frames": 24, | |
| "fps": 6, | |
| "quality": "Excellent", | |
| "speed": "Medium" | |
| }, | |
| "Wan-AI/Wan2.1-T2V-14B": { | |
| "name": "Wan2.1-T2V-14B (SOTA)", | |
| "description": "State-of-the-art text-to-video model with 14B parameters", | |
| "max_frames": 32, | |
| "fps": 8, | |
| "quality": "SOTA", | |
| "speed": "Medium", | |
| "resolutions": ["480P", "720P"], | |
| "features": ["Chinese & English text", "High motion dynamics", "Best quality"] | |
| } | |
| } | |
| # Voice options (gTTS only supports language, not gender/age) | |
| self.voices = { | |
| "Default (English)": "en" | |
| } | |
| def generate_video(self, prompt, model_id, num_frames=16, fps=8, num_inference_steps=25, guidance_scale=7.5, seed=None, resolution="480P", voice_script="", voice_type="Default (English)", add_voice=True): | |
| """Generate video from text prompt with optional voice (DEMO VERSION)""" | |
| try: | |
| # This is a demo version that simulates video generation | |
| logger.info(f"DEMO: Would generate video with prompt: {prompt}") | |
| logger.info(f"DEMO: Model: {model_id}, Frames: {num_frames}, FPS: {fps}") | |
| if add_voice and voice_script.strip(): | |
| logger.info(f"DEMO: Would add voice narration: {voice_script}") | |
| # Create a dummy video file for demonstration | |
| dummy_video_path = "demo_video.mp4" | |
| # For demo purposes, return a success message | |
| return dummy_video_path, f"DEMO: Video generation completed! (This is a test version - no actual video generated)" | |
| except Exception as e: | |
| logger.error(f"Error in demo video generation: {str(e)}") | |
| return None, f"Demo error: {str(e)}" | |
| def get_available_models(self): | |
| """Get list of available models""" | |
| return list(self.models.keys()) | |
| def get_model_info(self, model_id): | |
| """Get information about a specific model""" | |
| if model_id in self.models: | |
| return self.models[model_id] | |
| return None | |
| def get_available_voices(self): | |
| """Get list of available voices""" | |
| return list(self.voices.keys()) | |
| # Initialize the generator | |
| generator = TextToVideoGenerator() | |
| def create_interface(): | |
| """Create Gradio interface""" | |
| def generate_video_interface(prompt, model_id, num_frames, fps, num_inference_steps, guidance_scale, seed, resolution, voice_script, voice_type, add_voice): | |
| if not prompt.strip(): | |
| return None, "Please enter a prompt" | |
| return generator.generate_video( | |
| prompt=prompt, | |
| model_id=model_id, | |
| num_frames=num_frames, | |
| fps=fps, | |
| num_inference_steps=num_inference_steps, | |
| guidance_scale=guidance_scale, | |
| seed=seed, | |
| resolution=resolution, | |
| voice_script=voice_script, | |
| voice_type=voice_type, | |
| add_voice=add_voice | |
| ) | |
| # Custom CSS for professional styling | |
| custom_css = """ | |
| .gradio-container { | |
| max-width: 1200px !important; | |
| margin: 0 auto !important; | |
| } | |
| .header { | |
| text-align: center; | |
| padding: 2rem 0; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| border-radius: 15px; | |
| margin-bottom: 2rem; | |
| } | |
| .header h1 { | |
| font-size: 2.5rem; | |
| font-weight: 700; | |
| margin: 0; | |
| text-shadow: 2px 2px 4px rgba(0,0,0,0.3); | |
| } | |
| .header p { | |
| font-size: 1.1rem; | |
| margin: 0.5rem 0 0 0; | |
| opacity: 0.9; | |
| } | |
| .feature-card { | |
| background: white; | |
| border-radius: 10px; | |
| padding: 1.5rem; | |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |
| margin-bottom: 1rem; | |
| border-left: 4px solid #667eea; | |
| } | |
| .feature-card h3 { | |
| color: #333; | |
| margin: 0 0 0.5rem 0; | |
| font-size: 1.2rem; | |
| } | |
| .feature-card p { | |
| color: #666; | |
| margin: 0; | |
| font-size: 0.9rem; | |
| } | |
| .model-info { | |
| background: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 1rem; | |
| border: 1px solid #e9ecef; | |
| } | |
| .model-info h4 { | |
| color: #495057; | |
| margin: 0 0 0.5rem 0; | |
| font-size: 1rem; | |
| } | |
| .model-info p { | |
| color: #6c757d; | |
| margin: 0.25rem 0; | |
| font-size: 0.85rem; | |
| } | |
| .generate-btn { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; | |
| border: none !important; | |
| color: white !important; | |
| font-weight: 600 !important; | |
| padding: 1rem 2rem !important; | |
| border-radius: 10px !important; | |
| font-size: 1.1rem !important; | |
| transition: all 0.3s ease !important; | |
| } | |
| .generate-btn:hover { | |
| transform: translateY(-2px) !important; | |
| box-shadow: 0 6px 12px rgba(102, 126, 234, 0.4) !important; | |
| } | |
| .example-card { | |
| background: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 1rem; | |
| margin: 0.5rem 0; | |
| border: 1px solid #e9ecef; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| } | |
| .example-card:hover { | |
| background: #e9ecef; | |
| transform: translateX(5px); | |
| } | |
| .status-box { | |
| background: #e3f2fd; | |
| border: 1px solid #2196f3; | |
| border-radius: 8px; | |
| padding: 1rem; | |
| } | |
| .pricing-info { | |
| background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); | |
| border-radius: 10px; | |
| padding: 1rem; | |
| text-align: center; | |
| margin: 1rem 0; | |
| } | |
| .pricing-info h4 { | |
| color: #d84315; | |
| margin: 0 0 0.5rem 0; | |
| } | |
| .pricing-info p { | |
| color: #bf360c; | |
| margin: 0; | |
| font-size: 0.9rem; | |
| } | |
| .demo-notice { | |
| background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); | |
| border: 1px solid #ffc107; | |
| border-radius: 8px; | |
| padding: 1rem; | |
| margin: 1rem 0; | |
| text-align: center; | |
| } | |
| """ | |
| # Create interface | |
| with gr.Blocks(title="AI Video Creator Pro - DEMO", theme=gr.themes.Soft(), css=custom_css) as interface: | |
| # Professional Header | |
| with gr.Group(elem_classes="header"): | |
| gr.Markdown(""" | |
| # π¬ AI Video Creator Pro | |
| ### Transform Your Ideas Into Stunning Videos with AI-Powered Generation | |
| """) | |
| # Demo Notice | |
| with gr.Group(elem_classes="demo-notice"): | |
| gr.Markdown(""" | |
| ## π§ DEMO VERSION | |
| This is a demonstration of the professional UI. Video generation is simulated for testing purposes. | |
| The full version with actual AI video generation will be available once dependencies are resolved. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| # Main Input Section | |
| with gr.Group(elem_classes="feature-card"): | |
| gr.Markdown("## π― Video Generation") | |
| prompt = gr.Textbox( | |
| label="π Video Description", | |
| placeholder="Describe the video you want to create... (e.g., 'A majestic dragon soaring through a mystical forest with glowing mushrooms')", | |
| lines=3, | |
| max_lines=5, | |
| container=True | |
| ) | |
| with gr.Row(): | |
| model_id = gr.Dropdown( | |
| choices=generator.get_available_models(), | |
| value=generator.get_available_models()[0], | |
| label="π€ AI Model", | |
| info="Choose the AI model for video generation", | |
| container=True | |
| ) | |
| resolution = gr.Dropdown( | |
| choices=["480P", "720P"], | |
| value="480P", | |
| label="π Resolution (Wan2.1 only)", | |
| info="Select video resolution", | |
| visible=False, | |
| container=True | |
| ) | |
| with gr.Row(): | |
| num_frames = gr.Slider( | |
| minimum=8, | |
| maximum=32, | |
| value=16, | |
| step=1, | |
| label="ποΈ Video Length (Frames)", | |
| info="More frames = longer video" | |
| ) | |
| fps = gr.Slider( | |
| minimum=4, | |
| maximum=12, | |
| value=8, | |
| step=1, | |
| label="β‘ FPS", | |
| info="Frames per second" | |
| ) | |
| with gr.Row(): | |
| num_inference_steps = gr.Slider( | |
| minimum=10, | |
| maximum=50, | |
| value=25, | |
| step=1, | |
| label="π¨ Quality Steps", | |
| info="More steps = better quality but slower" | |
| ) | |
| guidance_scale = gr.Slider( | |
| minimum=1.0, | |
| maximum=20.0, | |
| value=7.5, | |
| step=0.5, | |
| label="π― Guidance Scale", | |
| info="Higher values = more prompt adherence" | |
| ) | |
| seed = gr.Number( | |
| label="π² Seed (Optional)", | |
| value=None, | |
| info="Set for reproducible results", | |
| container=True | |
| ) | |
| # Voice Section | |
| with gr.Group(elem_classes="feature-card"): | |
| gr.Markdown("## π€ Voice & Audio") | |
| with gr.Row(): | |
| add_voice = gr.Checkbox( | |
| label="π΅ Add Voice Narration", | |
| value=True, | |
| info="Enable to add professional voice-over" | |
| ) | |
| voice_type = gr.Dropdown( | |
| choices=generator.get_available_voices(), | |
| value="Default (English)", | |
| label="π£οΈ Voice Type", | |
| info="Select the voice for narration", | |
| container=True | |
| ) | |
| voice_script = gr.Textbox( | |
| label="π Narration Script (Optional)", | |
| placeholder="Enter your narration script here... (Leave blank to use video description)", | |
| lines=2, | |
| max_lines=3, | |
| info="If left blank, the video description will be used as narration", | |
| container=True | |
| ) | |
| # Generate Button | |
| generate_btn = gr.Button("π Generate Professional Video (DEMO)", variant="primary", size="lg", elem_classes="generate-btn") | |
| # Output Section | |
| with gr.Group(elem_classes="feature-card"): | |
| gr.Markdown("## πΊ Generated Video") | |
| status_text = gr.Textbox(label="π Status", interactive=False, elem_classes="status-box") | |
| video_output = gr.Video(label="π¬ Your Video", elem_classes="status-box") | |
| with gr.Column(scale=1): | |
| # Model Information | |
| with gr.Group(elem_classes="model-info"): | |
| gr.Markdown("## π€ AI Model Details") | |
| model_info = gr.JSON(label="Current Model Specifications", elem_classes="model-info") | |
| # Pricing Information | |
| with gr.Group(elem_classes="pricing-info"): | |
| gr.Markdown("## π° Pricing") | |
| gr.Markdown(""" | |
| **Free Tier:** 5 videos per day | |
| **Pro Plan:** $9.99/month | |
| - Unlimited videos | |
| - Priority processing | |
| - HD quality | |
| - Advanced features | |
| **Enterprise:** Contact us | |
| """) | |
| # Examples | |
| with gr.Group(): | |
| gr.Markdown("## π‘ Inspiration Examples") | |
| examples = [ | |
| ["A beautiful sunset over the ocean with waves crashing on the shore"], | |
| ["A cat playing with a ball of yarn in a cozy living room"], | |
| ["A futuristic city with flying cars and neon lights"], | |
| ["A butterfly emerging from a cocoon in a garden"], | |
| ["A rocket launching into space with fire and smoke"], | |
| ["Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage"], | |
| ["A majestic dragon soaring through a mystical forest with glowing mushrooms"] | |
| ] | |
| gr.Examples( | |
| examples=examples, | |
| inputs=prompt, | |
| label="Click to try these examples" | |
| ) | |
| # Features | |
| with gr.Group(): | |
| gr.Markdown("## β¨ Features") | |
| gr.Markdown(""" | |
| π¬ **Multiple AI Models** | |
| - State-of-the-art video generation | |
| - Quality vs speed options | |
| π€ **Professional Voice-Over** | |
| - Multiple voice types | |
| - Custom narration scripts | |
| π¨ **Advanced Controls** | |
| - Quality settings | |
| - Resolution options | |
| - Reproducible results | |
| β‘ **Fast Processing** | |
| - GPU acceleration | |
| - Optimized pipelines | |
| """) | |
| # Event handlers | |
| generate_btn.click( | |
| fn=generate_video_interface, | |
| inputs=[prompt, model_id, num_frames, fps, num_inference_steps, guidance_scale, seed, resolution, voice_script, voice_type, add_voice], | |
| outputs=[video_output, status_text] | |
| ) | |
| # Update model info when model changes | |
| def update_model_info(model_id): | |
| info = generator.get_model_info(model_id) | |
| return info | |
| # Show/hide resolution selector based on model | |
| def update_resolution_visibility(model_id): | |
| if model_id == "Wan-AI/Wan2.1-T2V-14B": | |
| return gr.Dropdown(visible=True) | |
| else: | |
| return gr.Dropdown(visible=False) | |
| model_id.change( | |
| fn=update_model_info, | |
| inputs=model_id, | |
| outputs=model_info | |
| ) | |
| model_id.change( | |
| fn=update_resolution_visibility, | |
| inputs=model_id, | |
| outputs=resolution | |
| ) | |
| # Load initial model info | |
| interface.load(lambda: generator.get_model_info(generator.get_available_models()[0]), outputs=model_info) | |
| return interface | |
| # Create and launch the interface | |
| interface = create_interface() | |
| interface.launch( | |
| server_name="0.0.0.0", | |
| server_port=7861, | |
| share=True, | |
| show_error=True | |
| ) |