ginipick commited on
Commit
3558e0d
·
verified ·
1 Parent(s): a5e046f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -10
app.py CHANGED
@@ -13,6 +13,7 @@ import io
13
  import requests
14
  from datetime import datetime
15
  import tempfile
 
16
 
17
  # API token setup
18
  api_token = os.getenv("RAPI_TOKEN")
@@ -30,12 +31,22 @@ ASPECT_RATIOS = {
30
  "9:21": "9:21 (Ultra Vertical)"
31
  }
32
 
 
 
 
 
33
  def update_prompt_placeholder(mode):
34
  """Update prompt placeholder based on mode"""
35
  if mode == "Text to Video":
36
- return gr.update(placeholder="Describe the video you want to create.\nExample: The sun rises slowly between tall buildings. [Ground-level follow shot] Bicycle tires roll over a dew-covered street at dawn.")
 
 
 
37
  else:
38
- return gr.update(placeholder="Describe how the image should move.\nExample: Camera slowly zooms in while clouds move across the sky. The subject's hair gently moves in the wind.")
 
 
 
39
 
40
  def update_image_input(mode):
41
  """Show/hide image input based on mode"""
@@ -44,6 +55,22 @@ def update_image_input(mode):
44
  else:
45
  return gr.update(visible=False)
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progress=gr.Progress()):
48
  """Main video generation function"""
49
 
@@ -90,22 +117,87 @@ def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progr
90
 
91
  input_params["image"] = f"data:image/png;base64,{image_base64}"
92
 
93
- progress(0.3, desc="Calling Replicate API...")
94
 
95
- # Run Replicate
96
- output = replicate.run(
97
- "bytedance/seedance-1-lite",
98
- input=input_params
99
  )
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  progress(0.7, desc="Downloading video...")
102
 
103
  # Get video data
104
  if hasattr(output, 'read'):
105
  video_data = output.read()
106
  else:
107
- # Download from URL
108
- response = requests.get(output)
109
  video_data = response.content
110
 
111
  # Save to temporary file
@@ -132,8 +224,12 @@ def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progr
132
 
133
  return video_path, info
134
 
 
 
135
  except Exception as e:
136
  error_msg = f"❌ Error occurred: {str(e)}"
 
 
137
  return None, error_msg
138
 
139
  # Gradio interface
@@ -212,7 +308,8 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
212
  prompt = gr.Textbox(
213
  label="✍️ Prompt",
214
  lines=5,
215
- placeholder="Describe the video you want to create.\nExample: The sun rises slowly between tall buildings. [Ground-level follow shot] Bicycle tires roll over a dew-covered street at dawn."
 
216
  )
217
 
218
  # Generate button
@@ -263,6 +360,12 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
263
  - Specify camera movements (e.g., zoom in, pan left, tracking shot)
264
  - Describe lighting and atmosphere (e.g., golden hour, dramatic lighting)
265
  - Indicate movement speed (e.g., slowly, rapidly, gently)
 
 
 
 
 
 
266
  """)
267
 
268
  # Examples
 
13
  import requests
14
  from datetime import datetime
15
  import tempfile
16
+ import time
17
 
18
  # API token setup
19
  api_token = os.getenv("RAPI_TOKEN")
 
31
  "9:21": "9:21 (Ultra Vertical)"
32
  }
33
 
34
+ # Default prompts
35
+ DEFAULT_TEXT_PROMPT = ""
36
+ DEFAULT_IMAGE_PROMPT = "Generate a video with smooth and natural movement. Objects should have visible motion while maintaining fluid transitions."
37
+
38
  def update_prompt_placeholder(mode):
39
  """Update prompt placeholder based on mode"""
40
  if mode == "Text to Video":
41
+ return gr.update(
42
+ placeholder="Describe the video you want to create.\nExample: The sun rises slowly between tall buildings. [Ground-level follow shot] Bicycle tires roll over a dew-covered street at dawn.",
43
+ value=""
44
+ )
45
  else:
46
+ return gr.update(
47
+ placeholder="Describe how the image should move.\nExample: Camera slowly zooms in while clouds move across the sky. The subject's hair gently moves in the wind.",
48
+ value=DEFAULT_IMAGE_PROMPT
49
+ )
50
 
51
  def update_image_input(mode):
52
  """Show/hide image input based on mode"""
 
55
  else:
56
  return gr.update(visible=False)
57
 
58
+ def wait_for_model_with_retry(replicate_client, model_name, max_retries=5, initial_wait=10):
59
+ """Wait for model to be ready with retry logic"""
60
+ for attempt in range(max_retries):
61
+ try:
62
+ # Try to get model info
63
+ model = replicate_client.models.get(model_name)
64
+ return True
65
+ except Exception as e:
66
+ if attempt < max_retries - 1:
67
+ wait_time = initial_wait * (attempt + 1)
68
+ print(f"Model not ready, waiting {wait_time} seconds... (Attempt {attempt + 1}/{max_retries})")
69
+ time.sleep(wait_time)
70
+ else:
71
+ return False
72
+ return False
73
+
74
  def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progress=gr.Progress()):
75
  """Main video generation function"""
76
 
 
117
 
118
  input_params["image"] = f"data:image/png;base64,{image_base64}"
119
 
120
+ progress(0.2, desc="Checking model availability...")
121
 
122
+ # Create Replicate client with extended timeout
123
+ client = replicate.Client(
124
+ api_token=token,
125
+ timeout=300 # 5 minutes timeout
126
  )
127
 
128
+ # Wait for model to be ready
129
+ model_ready = wait_for_model_with_retry(client, "bytedance/seedance-1-lite")
130
+ if not model_ready:
131
+ return None, "⏳ Model is still booting up. Please try again in a few minutes."
132
+
133
+ progress(0.3, desc="Calling Replicate API...")
134
+
135
+ # Run Replicate with retry logic
136
+ max_attempts = 3
137
+ for attempt in range(max_attempts):
138
+ try:
139
+ # Use prediction API for better control
140
+ prediction = client.predictions.create(
141
+ version="bytedance/seedance-1-lite:latest",
142
+ input=input_params,
143
+ webhook_completed=None
144
+ )
145
+
146
+ # Poll for completion with extended timeout
147
+ start_time = time.time()
148
+ timeout_seconds = 300 # 5 minutes
149
+
150
+ while prediction.status not in ["succeeded", "failed", "canceled"]:
151
+ if time.time() - start_time > timeout_seconds:
152
+ return None, "⏱️ Generation timed out. The server might be under heavy load. Please try again."
153
+
154
+ time.sleep(2) # Poll every 2 seconds
155
+ prediction.reload()
156
+
157
+ # Update progress
158
+ elapsed = time.time() - start_time
159
+ progress_val = min(0.3 + (elapsed / timeout_seconds) * 0.4, 0.7)
160
+ progress(progress_val, desc=f"Generating video... ({int(elapsed)}s)")
161
+
162
+ if prediction.status == "failed":
163
+ error_msg = getattr(prediction, 'error', 'Unknown error')
164
+ if "cold boot" in str(error_msg).lower() or "starting" in str(error_msg).lower():
165
+ if attempt < max_attempts - 1:
166
+ progress(0.3, desc=f"Model is starting up, retrying... (Attempt {attempt + 2}/{max_attempts})")
167
+ time.sleep(30) # Wait 30 seconds before retry
168
+ continue
169
+ return None, f"❌ Generation failed: {error_msg}"
170
+
171
+ elif prediction.status == "canceled":
172
+ return None, "❌ Generation was canceled."
173
+
174
+ # Success - get output
175
+ output = prediction.output
176
+ break
177
+
178
+ except replicate.exceptions.ReplicateError as e:
179
+ if "timeout" in str(e).lower() and attempt < max_attempts - 1:
180
+ progress(0.3, desc=f"Timeout occurred, retrying... (Attempt {attempt + 2}/{max_attempts})")
181
+ time.sleep(10)
182
+ continue
183
+ else:
184
+ return None, f"❌ Replicate API error: {str(e)}"
185
+ except Exception as e:
186
+ if attempt < max_attempts - 1:
187
+ progress(0.3, desc=f"Error occurred, retrying... (Attempt {attempt + 2}/{max_attempts})")
188
+ time.sleep(5)
189
+ continue
190
+ else:
191
+ return None, f"❌ Unexpected error: {str(e)}"
192
+
193
  progress(0.7, desc="Downloading video...")
194
 
195
  # Get video data
196
  if hasattr(output, 'read'):
197
  video_data = output.read()
198
  else:
199
+ # Download from URL with timeout
200
+ response = requests.get(output, timeout=60)
201
  video_data = response.content
202
 
203
  # Save to temporary file
 
224
 
225
  return video_path, info
226
 
227
+ except requests.exceptions.Timeout:
228
+ return None, "⏱️ Request timed out. The server might be under heavy load. Please try again in a few minutes."
229
  except Exception as e:
230
  error_msg = f"❌ Error occurred: {str(e)}"
231
+ if "timeout" in str(e).lower():
232
+ error_msg += "\n\n💡 Tip: The model might be cold starting. Please wait a minute and try again."
233
  return None, error_msg
234
 
235
  # Gradio interface
 
308
  prompt = gr.Textbox(
309
  label="✍️ Prompt",
310
  lines=5,
311
+ placeholder="Describe the video you want to create.\nExample: The sun rises slowly between tall buildings. [Ground-level follow shot] Bicycle tires roll over a dew-covered street at dawn.",
312
+ value=""
313
  )
314
 
315
  # Generate button
 
360
  - Specify camera movements (e.g., zoom in, pan left, tracking shot)
361
  - Describe lighting and atmosphere (e.g., golden hour, dramatic lighting)
362
  - Indicate movement speed (e.g., slowly, rapidly, gently)
363
+
364
+ ### Troubleshooting
365
+
366
+ - **Timeout errors**: The model might be cold starting. Wait 1-2 minutes and try again.
367
+ - **Model booting**: First requests after inactivity may take longer as the model boots up.
368
+ - **Extended wait times**: Complex prompts or server load may cause longer generation times.
369
  """)
370
 
371
  # Examples