Open-Source-Lab commited on
Commit
8fd8f96
·
verified ·
1 Parent(s): 2444f11

Update app.py

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