Willa666 Claude commited on
Commit
86f71b7
Β·
1 Parent(s): 782a3b9

πŸ”§ Fix Text-to-Video Timeout Issues

Browse files

## πŸ› οΈ Critical Timeout Fixes
- Increased base timeout from 5 to 15 minutes (more realistic)
- Reduced status check interval from 10s to 5s (better UX)
- Fixed timeout multipliers to be less aggressive

## πŸ”„ API Status Handling Improvements
- Added support for Novita's TASK_STATUS_* format
- Handle TASK_STATUS_PROCESSING, TASK_STATUS_SUCCEED correctly
- Improved status mapping for better reliability

## πŸ’‘ User Experience Enhancements
- Better timeout estimates and messaging
- Real-time elapsed time display
- More informative status messages
- Clear guidance for users during generation

## πŸ“Š New Timeout Calculations
- Lite models (720p, 5s): ~18 minutes max
- Pro models (1080p, 10s): ~37 minutes max
- More realistic timeouts prevent premature failures

This should resolve the text-to-video timeout issues.

πŸ€– Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (3) hide show
  1. api/novita_client.py +8 -3
  2. app.py +16 -2
  3. config.py +7 -7
api/novita_client.py CHANGED
@@ -123,16 +123,21 @@ class NovitaClient:
123
  task = result.get("task", {})
124
  status = task.get("status", "unknown")
125
 
126
- if status == "completed":
 
127
  videos = result.get("videos", [])
128
  if videos and videos[0].get("video_url"):
129
  return "completed", videos[0]["video_url"]
130
  return "completed", None
131
- elif status == "failed":
132
  reason = task.get("reason", "Generation failed")
133
  return "failed", reason
 
 
134
  else:
135
- return status, None
 
 
136
  elif response.status_code == 404:
137
  return "not_found", "Task not found"
138
  else:
 
123
  task = result.get("task", {})
124
  status = task.get("status", "unknown")
125
 
126
+ # Handle Novita API status format (TASK_STATUS_*)
127
+ if status in ["TASK_STATUS_SUCCEED", "completed"]:
128
  videos = result.get("videos", [])
129
  if videos and videos[0].get("video_url"):
130
  return "completed", videos[0]["video_url"]
131
  return "completed", None
132
+ elif status in ["TASK_STATUS_FAILED", "failed"]:
133
  reason = task.get("reason", "Generation failed")
134
  return "failed", reason
135
+ elif status in ["TASK_STATUS_PROCESSING", "TASK_STATUS_PENDING", "TASK_STATUS_QUEUED", "processing", "pending", "queued"]:
136
+ return "processing", None
137
  else:
138
+ # Return simplified status for display
139
+ simplified_status = status.replace("TASK_STATUS_", "").lower() if status.startswith("TASK_STATUS_") else status
140
+ return simplified_status, None
141
  elif response.status_code == 404:
142
  return "not_found", "Task not found"
143
  else:
app.py CHANGED
@@ -243,7 +243,10 @@ def generate_and_display_video(api_key, prompt, model_type, resolution, duration
243
  check_interval = Config.STATUS_CHECK_INTERVAL
244
 
245
  # Display estimated wait time
246
- st.info(f"⏱️ Estimated maximum wait time: {max_wait_time // 60}min {max_wait_time % 60}sec")
 
 
 
247
 
248
  for i in range(0, max_wait_time, check_interval):
249
  status, result = check_task_status(api_key, task_id)
@@ -266,7 +269,18 @@ def generate_and_display_video(api_key, prompt, model_type, resolution, duration
266
  else:
267
  progress = min((i / max_wait_time) * 90, 90) # Show maximum 90%
268
  progress_bar.progress(int(progress))
269
- status_placeholder.info(f"πŸ”„ Generating video... ({status})")
 
 
 
 
 
 
 
 
 
 
 
270
  time.sleep(check_interval)
271
  else:
272
  status_placeholder.warning(f"⏰ After waiting {max_wait_time // 60} minutes, still not completed. Video may still be generating. Task ID: {task_id}")
 
243
  check_interval = Config.STATUS_CHECK_INTERVAL
244
 
245
  # Display estimated wait time
246
+ estimated_min = max_wait_time // 60
247
+ estimated_sec = max_wait_time % 60
248
+ st.info(f"⏱️ Maximum wait time: {estimated_min}min {estimated_sec}sec (typically completes in 2-5 minutes)")
249
+ st.info("πŸ’‘ Keep this page open - it will automatically update when your video is ready!")
250
 
251
  for i in range(0, max_wait_time, check_interval):
252
  status, result = check_task_status(api_key, task_id)
 
269
  else:
270
  progress = min((i / max_wait_time) * 90, 90) # Show maximum 90%
271
  progress_bar.progress(int(progress))
272
+
273
+ # More user-friendly status messages
274
+ elapsed_min = i // 60
275
+ elapsed_sec = i % 60
276
+ if status == "processing":
277
+ status_msg = f"🎨 Creating your video... ({elapsed_min:02d}:{elapsed_sec:02d})"
278
+ elif status in ["pending", "queued"]:
279
+ status_msg = f"⏳ Your video is in queue... ({elapsed_min:02d}:{elapsed_sec:02d})"
280
+ else:
281
+ status_msg = f"πŸ”„ Generating video... ({status}) - {elapsed_min:02d}:{elapsed_sec:02d}"
282
+
283
+ status_placeholder.info(status_msg)
284
  time.sleep(check_interval)
285
  else:
286
  status_placeholder.warning(f"⏰ After waiting {max_wait_time // 60} minutes, still not completed. Video may still be generating. Task ID: {task_id}")
config.py CHANGED
@@ -16,15 +16,15 @@ class Config:
16
  DEFAULT_DURATION = int(os.getenv('DEFAULT_DURATION', '5'))
17
  DEFAULT_ASPECT_RATIO = os.getenv('DEFAULT_ASPECT_RATIO', '16:9')
18
 
19
- # Timeout Configuration
20
- BASE_TIMEOUT_SECONDS = int(os.getenv('BASE_TIMEOUT_SECONDS', '300'))
21
- PRO_MODEL_EXTRA_TIMEOUT = int(os.getenv('PRO_MODEL_EXTRA_TIMEOUT', '300'))
22
- RESOLUTION_720P_MULTIPLIER = float(os.getenv('RESOLUTION_720P_MULTIPLIER', '1.5'))
23
- RESOLUTION_1080P_MULTIPLIER = float(os.getenv('RESOLUTION_1080P_MULTIPLIER', '2.0'))
24
- LONG_VIDEO_EXTRA_TIMEOUT = int(os.getenv('LONG_VIDEO_EXTRA_TIMEOUT', '180'))
25
 
26
  # API Configuration
27
- STATUS_CHECK_INTERVAL = int(os.getenv('STATUS_CHECK_INTERVAL', '10'))
28
  MAX_RETRIES = int(os.getenv('MAX_RETRIES', '3'))
29
  REQUEST_TIMEOUT = int(os.getenv('REQUEST_TIMEOUT', '30'))
30
 
 
16
  DEFAULT_DURATION = int(os.getenv('DEFAULT_DURATION', '5'))
17
  DEFAULT_ASPECT_RATIO = os.getenv('DEFAULT_ASPECT_RATIO', '16:9')
18
 
19
+ # Timeout Configuration (increased for reliability)
20
+ BASE_TIMEOUT_SECONDS = int(os.getenv('BASE_TIMEOUT_SECONDS', '900')) # 15 minutes base
21
+ PRO_MODEL_EXTRA_TIMEOUT = int(os.getenv('PRO_MODEL_EXTRA_TIMEOUT', '600')) # 10 min extra for Pro
22
+ RESOLUTION_720P_MULTIPLIER = float(os.getenv('RESOLUTION_720P_MULTIPLIER', '1.2'))
23
+ RESOLUTION_1080P_MULTIPLIER = float(os.getenv('RESOLUTION_1080P_MULTIPLIER', '1.5'))
24
+ LONG_VIDEO_EXTRA_TIMEOUT = int(os.getenv('LONG_VIDEO_EXTRA_TIMEOUT', '300')) # 5 min extra for 10s videos
25
 
26
  # API Configuration
27
+ STATUS_CHECK_INTERVAL = int(os.getenv('STATUS_CHECK_INTERVAL', '5')) # Check every 5 seconds
28
  MAX_RETRIES = int(os.getenv('MAX_RETRIES', '3'))
29
  REQUEST_TIMEOUT = int(os.getenv('REQUEST_TIMEOUT', '30'))
30