import gradio as gr import requests import os import time import logging from PIL import Image import io # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Get API key (match your secret name - 'key' or 'Key') API_KEY = os.environ.get("key", os.environ.get("Key", "")) if not API_KEY: logger.error("❌ No API key found") def upload_to_temp_url(image): """Upload image to temporary hosting and return URL""" # For now, we'll need a temporary hosting solution # Option 1: Use imgbb.com API (need another key) # Option 2: Use Hugging Face's temp files (but need public URL) # Option 3: Keep URL input for now until we set up hosting # For simplicity now, we'll keep URL input # But we can add image preview return None def generate_video(image, prompt_text, model_id, progress=gr.Progress()): """Generate video using image upload and prompt""" if not API_KEY: yield "❌ API key not configured", None return try: progress(0, desc="Preparing request...") # For now, we need a publicly accessible image URL # This is a limitation - we need to host the uploaded image somewhere # Let's use a placeholder message until we implement hosting if image is None: yield "⚠️ Please upload an image", None return # For demo purposes, we'll keep URL input for now # But we show the uploaded image preview yield "⏳ Image uploaded. For now, please also provide a public URL (hosting service needed)", None return # The actual API call would go here once we have URL hosting except Exception as e: logger.error(f"❌ Error: {str(e)}") yield f"❌ Error: {str(e)}", None # Simple, clean interface with gr.Blocks(title="BytePlus Video Generator", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🎥 BytePlus Video Generator Upload an image and describe the video you want to generate """) with gr.Row(): with gr.Column(): # Image upload (input only) image_input = gr.Image( label="📤 Upload Starting Image", type="pil", height=300 ) # Text prompt prompt = gr.Textbox( label="📝 Video Description", placeholder="Describe what you want to see...", lines=3, value="At breakneck speed, drones thread through intricate obstacles --duration 5 --camerafixed false" ) # Model ID (hidden or simplified) model_id = gr.Textbox( label="Model ID", value="seedance-1-5-pro-251215", visible=False # Hide it for simplicity ) # Generate button generate_btn = gr.Button("🚀 Generate Video", variant="primary", size="lg") with gr.Column(): # Status messages status = gr.Textbox( label="Status", lines=2, interactive=False ) # Video output (player only, not uploader) video_output = gr.Video( label="🎬 Generated Video", interactive=False, # Can't upload, only view show_download_button=True, # Allow download height=300 ) # Example prompts (optional) gr.Markdown("---") gr.Markdown("### Example Prompts") with gr.Row(): gr.Button("Nature Drone").click( fn=lambda: "Aerial drone shot over mountains at sunrise, cinematic --duration 5 --camerafixed false", outputs=prompt ) gr.Button("City Race").click( fn=lambda: "Fast drone racing through futuristic city streets --duration 5 --camerafixed false", outputs=prompt ) gr.Button("Ocean Waves").click( fn=lambda: "Drone following waves at golden hour --duration 5 --camerafixed false", outputs=prompt ) # For now, show a note about image hosting gr.Markdown(""" --- ⚠️ **Note:** Currently requires publicly accessible image URLs. Working on direct image upload support! """) # Placeholder function for now def placeholder_gen(image, prompt, model): if image is None: return "Please upload an image first", None return "Image uploaded! (URL hosting coming soon)", None # Connect the button generate_btn.click( fn=placeholder_gen, inputs=[image_input, prompt, model_id], outputs=[status, video_output] ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0")