akhaliq HF Staff commited on
Commit
5e93ca8
·
verified ·
1 Parent(s): ff75c03

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +364 -0
app.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ I'll create a comprehensive text-to-video and image-to-video application using the Hugging Face Inference Client with fal-ai provider.
2
+
3
+ ```python
4
+ import gradio as gr
5
+ import os
6
+ from huggingface_hub import InferenceClient
7
+ import tempfile
8
+ import shutil
9
+ from pathlib import Path
10
+
11
+ # Initialize the client
12
+ client = InferenceClient(
13
+ provider="fal-ai",
14
+ api_key=os.environ.get("HF_TOKEN"),
15
+ bill_to="huggingface",
16
+ )
17
+
18
+ def text_to_video(prompt, duration=5, aspect_ratio="16:9", resolution="720p"):
19
+ """Generate video from text prompt"""
20
+ try:
21
+ if not prompt or prompt.strip() == "":
22
+ return None, "Please enter a text prompt"
23
+
24
+ # Generate video from text
25
+ video = client.text_to_video(
26
+ prompt,
27
+ model="akhaliq/veo3.1-fast",
28
+ )
29
+
30
+ # Save the video to a temporary file
31
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
32
+ tmp_file.write(video)
33
+ video_path = tmp_file.name
34
+
35
+ return video_path, f"✅ Video generated successfully from prompt: '{prompt[:50]}...'"
36
+
37
+ except Exception as e:
38
+ return None, f"❌ Error generating video: {str(e)}"
39
+
40
+ def image_to_video(image, prompt, duration=5, aspect_ratio="16:9", resolution="720p"):
41
+ """Generate video from image and prompt"""
42
+ try:
43
+ if image is None:
44
+ return None, "Please upload an image"
45
+
46
+ if not prompt or prompt.strip() == "":
47
+ return None, "Please enter a prompt describing the motion"
48
+
49
+ # Read the image file
50
+ if isinstance(image, str):
51
+ # If image is a file path
52
+ with open(image, "rb") as image_file:
53
+ input_image = image_file.read()
54
+ else:
55
+ # If image is already bytes or similar
56
+ import io
57
+ from PIL import Image as PILImage
58
+
59
+ # Convert to bytes if necessary
60
+ if isinstance(image, PILImage.Image):
61
+ buffer = io.BytesIO()
62
+ image.save(buffer, format='PNG')
63
+ input_image = buffer.getvalue()
64
+ else:
65
+ # Assume it's a numpy array or similar
66
+ pil_image = PILImage.fromarray(image)
67
+ buffer = io.BytesIO()
68
+ pil_image.save(buffer, format='PNG')
69
+ input_image = buffer.getvalue()
70
+
71
+ # Generate video from image
72
+ video = client.image_to_video(
73
+ input_image,
74
+ prompt=prompt,
75
+ model="akhaliq/veo3.1-fast-image-to-video",
76
+ )
77
+
78
+ # Save the video to a temporary file
79
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_file:
80
+ tmp_file.write(video)
81
+ video_path = tmp_file.name
82
+
83
+ return video_path, f"✅ Video generated successfully with motion: '{prompt[:50]}...'"
84
+
85
+ except Exception as e:
86
+ return None, f"❌ Error generating video: {str(e)}"
87
+
88
+ def clear_text_tab():
89
+ """Clear text-to-video tab"""
90
+ return "", None, ""
91
+
92
+ def clear_image_tab():
93
+ """Clear image-to-video tab"""
94
+ return None, "", None, ""
95
+
96
+ # Custom CSS for better styling
97
+ custom_css = """
98
+ .container {
99
+ max-width: 1200px;
100
+ margin: auto;
101
+ }
102
+ .header-link {
103
+ text-decoration: none;
104
+ color: #2196F3;
105
+ font-weight: bold;
106
+ }
107
+ .header-link:hover {
108
+ text-decoration: underline;
109
+ }
110
+ .status-box {
111
+ padding: 10px;
112
+ border-radius: 5px;
113
+ margin-top: 10px;
114
+ }
115
+ """
116
+
117
+ # Create the Gradio interface
118
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="AI Video Generator") as demo:
119
+ gr.Markdown(
120
+ """
121
+ # 🎬 AI Video Generator
122
+ ### Generate stunning videos from text or animate your images with AI
123
+ #### Powered by VEO 3.1 Fast Model | [Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder)
124
+ """
125
+ )
126
+
127
+ with gr.Tabs() as tabs:
128
+ # Text-to-Video Tab
129
+ with gr.Tab("📝 Text to Video", id=0):
130
+ gr.Markdown("### Transform your text descriptions into dynamic videos")
131
+
132
+ with gr.Row():
133
+ with gr.Column(scale=1):
134
+ text_prompt = gr.Textbox(
135
+ label="Text Prompt",
136
+ placeholder="Describe the video you want to create... (e.g., 'A young man walking on the street during sunset')",
137
+ lines=4,
138
+ max_lines=6
139
+ )
140
+
141
+ with gr.Accordion("Advanced Settings", open=False):
142
+ text_duration = gr.Slider(
143
+ minimum=1,
144
+ maximum=10,
145
+ value=5,
146
+ step=1,
147
+ label="Duration (seconds)",
148
+ info="Video duration in seconds"
149
+ )
150
+ text_aspect_ratio = gr.Dropdown(
151
+ choices=["16:9", "9:16", "1:1", "4:3", "21:9"],
152
+ value="16:9",
153
+ label="Aspect Ratio",
154
+ info="Video aspect ratio"
155
+ )
156
+ text_resolution = gr.Dropdown(
157
+ choices=["480p", "720p", "1080p"],
158
+ value="720p",
159
+ label="Resolution",
160
+ info="Video resolution"
161
+ )
162
+
163
+ with gr.Row():
164
+ text_generate_btn = gr.Button("🎬 Generate Video", variant="primary", scale=2)
165
+ text_clear_btn = gr.ClearButton(value="🗑️ Clear", scale=1)
166
+
167
+ text_status = gr.Textbox(
168
+ label="Status",
169
+ interactive=False,
170
+ visible=True,
171
+ elem_classes=["status-box"]
172
+ )
173
+
174
+ with gr.Column(scale=1):
175
+ text_video_output = gr.Video(
176
+ label="Generated Video",
177
+ autoplay=True,
178
+ show_download_button=True,
179
+ height=400
180
+ )
181
+
182
+ # Examples for text-to-video
183
+ gr.Examples(
184
+ examples=[
185
+ ["A serene beach at sunset with gentle waves"],
186
+ ["A bustling city street with neon lights at night"],
187
+ ["A majestic eagle soaring through mountain peaks"],
188
+ ["An astronaut floating in space near the International Space Station"],
189
+ ["Cherry blossoms falling in slow motion in a Japanese garden"],
190
+ ],
191
+ inputs=text_prompt,
192
+ label="Example Prompts"
193
+ )
194
+
195
+ # Image-to-Video Tab
196
+ with gr.Tab("🖼️ Image to Video", id=1):
197
+ gr.Markdown("### Bring your static images to life with motion")
198
+
199
+ with gr.Row():
200
+ with gr.Column(scale=1):
201
+ image_input = gr.Image(
202
+ label="Upload Image",
203
+ type="pil",
204
+ height=300
205
+ )
206
+
207
+ image_prompt = gr.Textbox(
208
+ label="Motion Prompt",
209
+ placeholder="Describe how the image should move... (e.g., 'The cat starts to dance')",
210
+ lines=3,
211
+ max_lines=5
212
+ )
213
+
214
+ with gr.Accordion("Advanced Settings", open=False):
215
+ image_duration = gr.Slider(
216
+ minimum=1,
217
+ maximum=10,
218
+ value=5,
219
+ step=1,
220
+ label="Duration (seconds)",
221
+ info="Video duration in seconds"
222
+ )
223
+ image_aspect_ratio = gr.Dropdown(
224
+ choices=["16:9", "9:16", "1:1", "4:3", "21:9"],
225
+ value="16:9",
226
+ label="Aspect Ratio",
227
+ info="Video aspect ratio"
228
+ )
229
+ image_resolution = gr.Dropdown(
230
+ choices=["480p", "720p", "1080p"],
231
+ value="720p",
232
+ label="Resolution",
233
+ info="Video resolution"
234
+ )
235
+
236
+ with gr.Row():
237
+ image_generate_btn = gr.Button("🎬 Animate Image", variant="primary", scale=2)
238
+ image_clear_btn = gr.ClearButton(value="🗑️ Clear", scale=1)
239
+
240
+ image_status = gr.Textbox(
241
+ label="Status",
242
+ interactive=False,
243
+ visible=True,
244
+ elem_classes=["status-box"]
245
+ )
246
+
247
+ with gr.Column(scale=1):
248
+ image_video_output = gr.Video(
249
+ label="Generated Video",
250
+ autoplay=True,
251
+ show_download_button=True,
252
+ height=400
253
+ )
254
+
255
+ # Examples for image-to-video
256
+ gr.Examples(
257
+ examples=[
258
+ [None, "The person starts walking forward"],
259
+ [None, "The animal begins to run"],
260
+ [None, "Camera slowly zooms in while the subject smiles"],
261
+ [None, "The flowers sway gently in the breeze"],
262
+ [None, "The clouds move across the sky in time-lapse"],
263
+ ],
264
+ inputs=[image_input, image_prompt],
265
+ label="Example Motion Prompts"
266
+ )
267
+
268
+ # How to Use section
269
+ with gr.Accordion("📖 How to Use", open=False):
270
+ gr.Markdown(
271
+ """
272
+ ### Text to Video:
273
+ 1. Enter a detailed description of the video you want to create
274
+ 2. Optionally adjust advanced settings (duration, aspect ratio, resolution)
275
+ 3. Click "Generate Video" and wait for the AI to create your video
276
+ 4. Download or preview your generated video
277
+
278
+ ### Image to Video:
279
+ 1. Upload an image you want to animate
280
+ 2. Describe the motion or action you want to add to the image
281
+ 3. Optionally adjust advanced settings
282
+ 4. Click "Animate Image" to bring your image to life
283
+ 5. Download or preview your animated video
284
+
285
+ ### Tips for Better Results:
286
+ - Be specific and descriptive in your prompts
287
+ - For image-to-video, describe natural motions that fit the image
288
+ - Use high-quality input images for better results
289
+ - Experiment with different prompts to get the desired effect
290
+ """
291
+ )
292
+
293
+ # Event handlers
294
+ text_generate_btn.click(
295
+ fn=text_to_video,
296
+ inputs=[text_prompt, text_duration, text_aspect_ratio, text_resolution],
297
+ outputs=[text_video_output, text_status],
298
+ show_progress="full"
299
+ )
300
+
301
+ text_clear_btn.click(
302
+ fn=clear_text_tab,
303
+ inputs=[],
304
+ outputs=[text_prompt, text_video_output, text_status]
305
+ )
306
+
307
+ image_generate_btn.click(
308
+ fn=image_to_video,
309
+ inputs=[image_input, image_prompt, image_duration, image_aspect_ratio, image_resolution],
310
+ outputs=[image_video_output, image_status],
311
+ show_progress="full"
312
+ )
313
+
314
+ image_clear_btn.click(
315
+ fn=clear_image_tab,
316
+ inputs=[],
317
+ outputs=[image_input, image_prompt, image_video_output, image_status]
318
+ )
319
+
320
+ # Launch the app
321
+ if __name__ == "__main__":
322
+ demo.launch(
323
+ show_api=True,
324
+ share=False,
325
+ show_error=True
326
+ )
327
+ ```
328
+
329
+ This application provides:
330
+
331
+ ## Features:
332
+
333
+ 1. **Text-to-Video Generation**:
334
+ - Convert text descriptions into videos
335
+ - Customizable duration, aspect ratio, and resolution
336
+ - Example prompts for inspiration
337
+ - Status updates and error handling
338
+
339
+ 2. **Image-to-Video Animation**:
340
+ - Upload static images and add motion
341
+ - Describe the desired animation with text prompts
342
+ - Same customization options as text-to-video
343
+ - Example motion descriptions
344
+
345
+ 3. **User-Friendly Interface**:
346
+ - Clean, tabbed interface separating the two functions
347
+ - Advanced settings in collapsible accordions
348
+ - Real-time status updates
349
+ - Download capability for generated videos
350
+ - Clear buttons to reset inputs
351
+
352
+ 4. **Professional Design**:
353
+ - Soft theme for pleasant viewing
354
+ - Responsive layout
355
+ - Proper error handling and user feedback
356
+ - "Built with anycoder" attribution link in header
357
+
358
+ 5. **Additional Features**:
359
+ - Auto-play for generated videos
360
+ - Example inputs to help users get started
361
+ - How-to-use guide
362
+ - Progress indicators during generation
363
+
364
+ The app handles both text-to-video and image-to-video generation using the VEO 3.1 Fast models through the Hugging Face Inference Client with fal-ai provider. It includes proper error handling, user feedback, and a clean interface that makes it easy for users to generate AI videos.