Spaces:
Running
Running
| import gradio as gr | |
| import traceback | |
| from workflow import agent_workflow | |
| def run_workflow(videos, description, duration, music): | |
| """ | |
| Generator function that runs the workflow and yields progress updates in real-time. | |
| According to Gradio's streaming outputs guide, generator functions yield values | |
| that update the UI in real-time as they're produced. | |
| """ | |
| # Handle empty or None input | |
| if not videos or (isinstance(videos, list) and len(videos) == 0): | |
| yield None, "β Please upload at least one video file.", "", "", None | |
| return | |
| try: | |
| # Iterate through the generator from agent_workflow | |
| # This will yield progress updates in real-time | |
| for ( | |
| final_path, | |
| summary_json, | |
| script_json, | |
| thumbnail_path, | |
| status, | |
| ) in agent_workflow( | |
| video_inputs=videos, | |
| user_description=description.strip() if description else None, | |
| target_duration=float(duration), | |
| generate_music=bool(music), | |
| ): | |
| # Yield each progress update to Gradio | |
| # Gradio will automatically update the UI with each yield | |
| yield final_path, status, summary_json, script_json, thumbnail_path | |
| except Exception as e: | |
| error_msg = f"β Error: {str(e)}\n\nDetails: {traceback.format_exc()}" | |
| yield None, error_msg, "", "", None | |
| def workflow_ui(): | |
| """Create the full workflow UI interface.""" | |
| with gr.Column(): | |
| # Header | |
| gr.Markdown( | |
| """ | |
| # π¬ Vidzly - Video Creation Workflow | |
| Transform your raw footage into a polished video with AI-powered editing. | |
| Our workflow uses advanced AI tools to analyze, plan, and create your video automatically. | |
| Upload your videos, describe your vision, and let the AI handle the rest! | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Input section | |
| gr.Markdown("### π₯ Input") | |
| video_input = gr.File( | |
| label="Upload Video(s)", | |
| file_count="multiple", | |
| file_types=["video"], | |
| height=200, | |
| ) | |
| user_description = gr.Textbox( | |
| label="Describe Your Vision (Optional)", | |
| placeholder="e.g., energetic and fast-paced, calm and cinematic, fun and colorful...", | |
| lines=3, | |
| info="Describe the mood, style, or vibe you want for your video", | |
| ) | |
| with gr.Row(): | |
| target_duration = gr.Slider( | |
| value=30.0, | |
| label="Target Duration (seconds)", | |
| minimum=5.0, | |
| maximum=60.0, | |
| step=1.0, | |
| info="Length of the final video", | |
| ) | |
| generate_music = gr.Checkbox( | |
| value=True, | |
| label="Generate Background Music", | |
| info="Automatically generate music matching the video mood", | |
| ) | |
| create_btn = gr.Button( | |
| "π¬ Create Video", | |
| variant="primary", | |
| size="lg", | |
| ) | |
| gr.Markdown("### π Status") | |
| progress_status = gr.Textbox( | |
| label="Status", | |
| value="Ready to create your video!", | |
| interactive=False, | |
| lines=10, | |
| max_lines=20, | |
| ) | |
| with gr.Column(scale=2): | |
| # Output section | |
| gr.Markdown("### π’ Output") | |
| thumbnail_image = gr.Image( | |
| label="Generated Thumbnail", | |
| type="filepath", | |
| height=400, | |
| visible=True, | |
| ) | |
| final_video = gr.Video( | |
| label="Final Video", | |
| height=400, | |
| ) | |
| with gr.Accordion("π Details", open=False): | |
| summary_display = gr.Textbox( | |
| label="Video Analysis Summary", | |
| lines=10, | |
| max_lines=20, | |
| interactive=False, | |
| ) | |
| script_display = gr.Textbox( | |
| label="Generated Script", | |
| lines=10, | |
| max_lines=20, | |
| interactive=False, | |
| ) | |
| # Connect the button to the workflow | |
| create_btn.click( | |
| fn=run_workflow, | |
| inputs=[ | |
| video_input, | |
| user_description, | |
| target_duration, | |
| generate_music, | |
| ], | |
| outputs=[ | |
| final_video, | |
| progress_status, | |
| summary_display, | |
| script_display, | |
| thumbnail_image, | |
| ], | |
| ) | |