Chand11 commited on
Commit
2c286ed
Β·
verified Β·
1 Parent(s): 910dcb6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -46
app.py CHANGED
@@ -256,58 +256,99 @@ def render_video_from_code(code, quality):
256
  return f"❌ {e}", None
257
 
258
  def render_video(prompt, template, duration, quality):
259
- """Generate and render video"""
260
  if not prompt:
261
  yield "❌ Enter a prompt!", None, None
262
  return
263
 
264
- try:
265
- temp_dir = Path(tempfile.mkdtemp(prefix="manim_"))
266
-
267
- yield f"πŸ€– Generating {template} video ({duration})...", None, None
268
-
269
- code, error = generate_code_with_gemini(prompt, template, duration, quality)
270
-
271
- if error:
272
- yield error, None, None
273
- return
274
-
275
- if "```python" in code:
276
- code = code.split("```python")[1].split("```")[0]
277
- elif "```" in code:
278
- code = code.split("```")[1].split("```")[0]
279
- code = code.strip()
280
-
281
- code = fix_all_known_errors(code)
282
-
283
- match = re.search(r'class\s+(\w+)\s*\(Scene\)', code)
284
- if not match:
285
- yield "❌ No Scene class!", code, None
286
- return
287
-
288
- class_name = match.group(1)
289
- code_file = temp_dir / "animation.py"
290
- code_file.write_text(code)
291
-
292
- yield f"🎬 Rendering {class_name}...", code, None
293
-
294
- quality_map = {'Low (fast)': '-ql', 'Medium': '-qm', 'High (1080p)': '-qh'}
295
- quality_flag = quality_map.get(quality, '-qm')
296
-
297
- cmd = f"manim {code_file} {class_name} {quality_flag} --disable_caching --media_dir {temp_dir}/media"
298
- result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
299
-
300
- if result.returncode == 0:
301
- videos = list((temp_dir / "media").rglob("*.mp4"))
302
- if videos:
303
- yield "βœ… YouTube-ready video rendered! πŸŽ‰", code, str(videos[0])
304
  else:
305
- yield "❌ Video not found", code, None
306
- else:
307
- yield f"❌ Failed:\n{result.stderr[-500:]}", code, None
308
 
309
- except Exception as e:
310
- yield f"❌ {e}", None, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
  # Gradio Interface
313
  with gr.Blocks(title="YouTube Math Explainer") as demo:
 
256
  return f"❌ {e}", None
257
 
258
  def render_video(prompt, template, duration, quality):
259
+ """Generate and render video with auto-retry"""
260
  if not prompt:
261
  yield "❌ Enter a prompt!", None, None
262
  return
263
 
264
+ MAX_ATTEMPTS = 3
265
+
266
+ for attempt in range(1, MAX_ATTEMPTS + 1):
267
+ try:
268
+ temp_dir = Path(tempfile.mkdtemp(prefix="manim_"))
269
+
270
+ if attempt == 1:
271
+ yield f"πŸ€– Generating {template} video ({duration})...", None, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  else:
273
+ yield f"πŸ”„ Attempt {attempt}/{MAX_ATTEMPTS} - Simplifying code...", None, None
 
 
274
 
275
+ # Adjust prompt complexity based on attempt
276
+ if attempt == 1:
277
+ current_prompt = prompt
278
+ elif attempt == 2:
279
+ current_prompt = f"KEEP IT VERY SIMPLE. {prompt}. Use only basic shapes and text, no complex arrangements."
280
+ else:
281
+ current_prompt = f"EXTREMELY SIMPLE VERSION: {prompt}. Only 2-3 simple elements, no arrays, no loops, no complex positioning."
282
+
283
+ code, error = generate_code_with_gemini(current_prompt, template, duration, quality)
284
+
285
+ if error:
286
+ if attempt < MAX_ATTEMPTS:
287
+ continue
288
+ yield error, None, None
289
+ return
290
+
291
+ if "```python" in code:
292
+ code = code.split("```python")[1].split("```")[0]
293
+ elif "```" in code:
294
+ code = code.split("```")[1].split("```")[0]
295
+ code = code.strip()
296
+
297
+ code = fix_all_known_errors(code)
298
+
299
+ # Extra safety fixes for common index errors
300
+ # Remove array/list indexing that might fail
301
+ code = re.sub(r'\[(\d+)\]\.', '[0].', code) # Replace [N] with [0]
302
+ code = re.sub(r'for\s+\w+\s+in\s+range\([^)]+\):', '# Loop removed', code) # Comment out loops
303
+
304
+ match = re.search(r'class\s+(\w+)\s*\(Scene\)', code)
305
+ if not match:
306
+ if attempt < MAX_ATTEMPTS:
307
+ continue
308
+ yield "❌ No Scene class!", code, None
309
+ return
310
+
311
+ class_name = match.group(1)
312
+ code_file = temp_dir / "animation.py"
313
+ code_file.write_text(code)
314
+
315
+ yield f"🎬 Rendering (attempt {attempt})...", code, None
316
+
317
+ quality_map = {'Low (fast)': '-ql', 'Medium': '-qm', 'High (1080p)': '-qh'}
318
+ quality_flag = quality_map.get(quality, '-qm')
319
+
320
+ cmd = f"manim {code_file} {class_name} {quality_flag} --disable_caching --media_dir {temp_dir}/media"
321
+ result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
322
+
323
+ if result.returncode == 0:
324
+ videos = list((temp_dir / "media").rglob("*.mp4"))
325
+ if videos:
326
+ if attempt > 1:
327
+ yield f"βœ… Success on attempt {attempt}! (Simplified version) πŸŽ‰", code, str(videos[0])
328
+ else:
329
+ yield "βœ… YouTube-ready video rendered! πŸŽ‰", code, str(videos[0])
330
+ return
331
+ else:
332
+ if attempt < MAX_ATTEMPTS:
333
+ continue
334
+ yield "❌ Video not found", code, None
335
+ return
336
+ else:
337
+ # Rendering failed, try again with simpler code
338
+ if attempt < MAX_ATTEMPTS:
339
+ error_snippet = result.stderr[-200:] if result.stderr else "Unknown error"
340
+ print(f"Attempt {attempt} failed: {error_snippet}")
341
+ continue
342
+ else:
343
+ yield f"❌ All {MAX_ATTEMPTS} attempts failed. Last error:\n{result.stderr[-500:]}", code, None
344
+ return
345
+
346
+ except Exception as e:
347
+ if attempt < MAX_ATTEMPTS:
348
+ print(f"Attempt {attempt} crashed: {e}")
349
+ continue
350
+ yield f"❌ Error after {MAX_ATTEMPTS} attempts: {e}", None, None
351
+ return
352
 
353
  # Gradio Interface
354
  with gr.Blocks(title="YouTube Math Explainer") as demo: