devendergarg14 commited on
Commit
6ebad65
·
verified ·
1 Parent(s): 7022c93

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -28
app.py CHANGED
@@ -12,37 +12,27 @@ import tempfile
12
  # 1. Helper Functions
13
  # ---------------------------------------------------------
14
 
15
- def modify_animation_times(code: str, factor: float = 1.0, for_precheck: bool = False) -> str:
16
  """
17
- Modifies wait() and run_time in the code.
18
- - Pre-Check: Uses a robust regex to replace any run_time value with 0.01.
19
- - Preview: Scales numeric times by a factor.
20
  """
21
- if for_precheck:
22
- print("⚡ Optimizing code for Pre-check (Zero Latency)...", flush=True)
23
- # Use a tiny non-zero value to prevent ZeroDivisionError
24
- replacement_time = "0.01"
25
-
26
- # This robust regex handles: run_time=2.0, run_time=my_var, run_time=(some_function(a, b))
27
- run_time_pattern = re.compile(r"(run_time\s*=\s*)(\(.*\)|[a-zA-Z_]\w*|\d+\.?\d*)")
28
- code = run_time_pattern.sub(fr"\g<1>{replacement_time}", code)
29
-
30
- # The wait regex is simpler and can remain as is
31
- code = re.sub(r"self\.wait\s*\([^)]*\)", f"self.wait({replacement_time})", code)
32
- return code
33
-
34
- print(f"⚡ Scaling animation times by a factor of {factor} for preview.", flush=True)
35
- MIN_RUN_TIME = 0.1
36
 
37
  def scale_match(m, is_wait):
38
  try:
39
  val = float(m.group(2))
40
  new_val = val * factor
 
41
  final_val = new_val if is_wait else max(new_val, MIN_RUN_TIME)
42
  return f"{m.group(1)}{final_val:.3f}"
43
  except ValueError:
44
- return m.group(0) # Ignore if it's not a number (e.g., a variable)
 
45
 
 
46
  code = re.sub(r"(run_time\s*=\s*)(\d+\.?\d*)", lambda m: scale_match(m, False), code)
47
  code = re.sub(r"(self\.wait\s*\(\s*)(\d+\.?\d*)", lambda m: scale_match(m, True), code)
48
  return code
@@ -50,11 +40,14 @@ def modify_animation_times(code: str, factor: float = 1.0, for_precheck: bool =
50
  def run_manim_pre_check(code_str: str) -> (bool, str):
51
  """
52
  Runs Manim with '-s'.
53
- - A strong regex now prevents speed-hack errors, so we don't need special error handling.
54
- - Soft Pass on Timeout remains as a fallback for true infinite loops.
 
55
  """
56
  print("🕵️ Running fast pre-check with 'manim -s'...", flush=True)
57
- fast_code = modify_animation_times(code_str, for_precheck=True)
 
 
58
 
59
  with open("scene_pre_check.py", "w", encoding="utf-8") as f:
60
  f.write(fast_code)
@@ -115,6 +108,7 @@ def run_manim(code_str, orientation, quality, timeout):
115
 
116
  try:
117
  process = subprocess.run(cmd, capture_output=True, timeout=timeout_sec, check=False)
 
118
  stdout_log = process.stdout.decode('utf-8', 'ignore')
119
  stderr_log = process.stderr.decode('utf-8', 'ignore')
120
  full_logs = f"--- MANIM STDOUT ---\n{stdout_log}\n\n--- MANIM STDERR ---\n{stderr_log}"
@@ -182,7 +176,7 @@ def render_video_from_code(code, orientation, quality, timeout, preview_factor):
182
  return None, "Error: No valid code.", gr.Button(visible=False)
183
 
184
  if quality == "Preview (360p)":
185
- code_to_render = modify_animation_times(code, factor=float(preview_factor) or 0.5, for_precheck=False)
186
  else:
187
  code_to_render = code
188
 
@@ -302,7 +296,6 @@ def merge_audio_to_video(video_input, audio_input):
302
  # 4. Gradio Interface
303
  # ---------------------------------------------------------
304
 
305
- # Define the default code here to be used in the UI
306
  DEFAULT_CODE = """from manim import *
307
 
308
  class GenScene(Scene):
@@ -316,7 +309,6 @@ with gr.Blocks(title="Manim Render & Audio Tool") as demo:
316
  with gr.Tab("🎬 Manim Video Renderer"):
317
  with gr.Row():
318
  with gr.Column(scale=1):
319
- # Use the DEFAULT_CODE variable directly here
320
  code_input = gr.Code(label="Python Code", language="python", value=DEFAULT_CODE, visible=True)
321
  orientation_opt = gr.Radio(choices=["Landscape (16:9)", "Portrait (9:16)"], value="Portrait (9:16)", label="Orientation", visible=True)
322
  quality_opt = gr.Dropdown(choices=["Preview (360p)", "480p", "720p", "1080p", "4k"], value="Preview (360p)", label="Quality", visible=True)
@@ -355,6 +347,4 @@ with gr.Blocks(title="Manim Render & Audio Tool") as demo:
355
  )
356
 
357
  if __name__ == "__main__":
358
- # The default code is now handled directly in the UI definition,
359
- # so no extra logic is needed here.
360
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
12
  # 1. Helper Functions
13
  # ---------------------------------------------------------
14
 
15
+ def modify_animation_times(code: str, factor: float) -> str:
16
  """
17
+ Scales all numeric run_time and wait() values by a given factor.
18
+ This single, safe function is now used for both Pre-check and Preview modes.
 
19
  """
20
+ print(f"⚡ Scaling animation times by a factor of {factor}...", flush=True)
21
+ # A safe minimum to prevent Manim from crashing with run_time=0
22
+ MIN_RUN_TIME = 0.01
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  def scale_match(m, is_wait):
25
  try:
26
  val = float(m.group(2))
27
  new_val = val * factor
28
+ # For waits, we can go low. For run_time, we must stay above zero.
29
  final_val = new_val if is_wait else max(new_val, MIN_RUN_TIME)
30
  return f"{m.group(1)}{final_val:.3f}"
31
  except ValueError:
32
+ # This happens if run_time is a variable. We safely ignore it.
33
+ return m.group(0)
34
 
35
+ # This safe regex only matches explicit numbers, preventing SyntaxErrors.
36
  code = re.sub(r"(run_time\s*=\s*)(\d+\.?\d*)", lambda m: scale_match(m, False), code)
37
  code = re.sub(r"(self\.wait\s*\(\s*)(\d+\.?\d*)", lambda m: scale_match(m, True), code)
38
  return code
 
40
  def run_manim_pre_check(code_str: str) -> (bool, str):
41
  """
42
  Runs Manim with '-s'.
43
+ - Uses the safe `modify_animation_times` function with a small factor for a significant speedup.
44
+ - Errors are now always considered critical because the modification is safe.
45
+ - Soft Pass on Timeout remains as a fallback.
46
  """
47
  print("🕵️ Running fast pre-check with 'manim -s'...", flush=True)
48
+ # Using a factor of 0.2 makes a 10-second animation take 2 seconds in pre-check.
49
+ # This is a good balance of speed and reliability.
50
+ fast_code = modify_animation_times(code_str, factor=0.2)
51
 
52
  with open("scene_pre_check.py", "w", encoding="utf-8") as f:
53
  f.write(fast_code)
 
108
 
109
  try:
110
  process = subprocess.run(cmd, capture_output=True, timeout=timeout_sec, check=False)
111
+
112
  stdout_log = process.stdout.decode('utf-8', 'ignore')
113
  stderr_log = process.stderr.decode('utf-8', 'ignore')
114
  full_logs = f"--- MANIM STDOUT ---\n{stdout_log}\n\n--- MANIM STDERR ---\n{stderr_log}"
 
176
  return None, "Error: No valid code.", gr.Button(visible=False)
177
 
178
  if quality == "Preview (360p)":
179
+ code_to_render = modify_animation_times(code, factor=float(preview_factor) or 0.5)
180
  else:
181
  code_to_render = code
182
 
 
296
  # 4. Gradio Interface
297
  # ---------------------------------------------------------
298
 
 
299
  DEFAULT_CODE = """from manim import *
300
 
301
  class GenScene(Scene):
 
309
  with gr.Tab("🎬 Manim Video Renderer"):
310
  with gr.Row():
311
  with gr.Column(scale=1):
 
312
  code_input = gr.Code(label="Python Code", language="python", value=DEFAULT_CODE, visible=True)
313
  orientation_opt = gr.Radio(choices=["Landscape (16:9)", "Portrait (9:16)"], value="Portrait (9:16)", label="Orientation", visible=True)
314
  quality_opt = gr.Dropdown(choices=["Preview (360p)", "480p", "720p", "1080p", "4k"], value="Preview (360p)", label="Quality", visible=True)
 
347
  )
348
 
349
  if __name__ == "__main__":
 
 
350
  demo.launch(server_name="0.0.0.0", server_port=7860)