Spaces:
Running
Running
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 | |
) |