devendergarg14 commited on
Commit
8bd2e7e
·
verified ·
1 Parent(s): 52795f7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -9
app.py CHANGED
@@ -203,7 +203,6 @@ def get_media_duration(file_path):
203
  def build_atempo_filter(factor):
204
  """Builds a chained atempo filter for FFmpeg to handle extreme speed changes."""
205
  filters = []
206
- # FFmpeg's atempo filter is limited to the range [0.5, 100.0]
207
  while factor > 100.0:
208
  filters.append("atempo=100.0"); factor /= 100.0
209
  while factor < 0.5:
@@ -217,10 +216,8 @@ def decode_base64_to_tempfile(data_obj):
217
  if not data_obj or 'data' not in data_obj:
218
  return None
219
 
220
- # Gradio sends base64 data in the format "data:video/mp4;base64,xxxx..."
221
  header, encoded_data = data_obj['data'].split(",", 1)
222
  file_extension = header.split('/')[1].split(';')[0]
223
-
224
  decoded_data = base64.b64decode(encoded_data)
225
 
226
  with tempfile.NamedTemporaryFile(delete=False, suffix=f".{file_extension}") as tmp_file:
@@ -236,10 +233,8 @@ def merge_audio_to_video(video_input, audio_input):
236
  temp_files_to_clean = []
237
 
238
  try:
239
- # --- Handle UI call (inputs are file paths) ---
240
  if isinstance(video_input, str) and os.path.exists(video_input):
241
  video_path = video_input
242
- # --- Handle API call (inputs are base64 dictionaries) ---
243
  elif isinstance(video_input, dict):
244
  print("API call detected: Decoding video from base64.", flush=True)
245
  video_path = decode_base64_to_tempfile(video_input)
@@ -252,7 +247,6 @@ def merge_audio_to_video(video_input, audio_input):
252
  audio_path = decode_base64_to_tempfile(audio_input)
253
  if audio_path: temp_files_to_clean.append(audio_path)
254
 
255
- # --- Validation ---
256
  if not video_path or not audio_path:
257
  return None, "Error: Missing video or audio file. Please provide both."
258
 
@@ -265,7 +259,6 @@ def merge_audio_to_video(video_input, audio_input):
265
  if video_duration == 0:
266
  return None, "Error: Input video has zero duration."
267
 
268
- # --- Core FFmpeg Logic ---
269
  speed_factor = audio_duration / video_duration
270
  atempo_filter = build_atempo_filter(speed_factor)
271
 
@@ -296,7 +289,6 @@ def merge_audio_to_video(video_input, audio_input):
296
  return output_path, "✅ Audio merged successfully!"
297
 
298
  finally:
299
- # --- Cleanup ---
300
  print(f"Cleaning up {len(temp_files_to_clean)} temporary files...", flush=True)
301
  for f in temp_files_to_clean:
302
  try:
@@ -308,10 +300,22 @@ def merge_audio_to_video(video_input, audio_input):
308
  # 3. Gradio Interface
309
  # ---------------------------------------------------------
310
 
 
 
 
 
 
 
 
 
 
 
 
311
  with gr.Blocks(title="Manim Render & Audio Tool") as demo:
312
  with gr.Tab("🎬 Manim Video Renderer"):
313
  with gr.Row():
314
  with gr.Column(scale=1):
 
315
  code_input = gr.Code(label="Python Code", language="python", value=DEFAULT_CODE, visible=True)
316
  orientation_opt = gr.Radio(choices=["Landscape (16:9)", "Portrait (9:16)"], value="Portrait (9:16)", label="Orientation", visible=True)
317
  quality_opt = gr.Dropdown(choices=["Preview (360p)", "480p", "720p", "1080p", "4k"], value="Preview (360p)", label="Quality", visible=True)
@@ -336,7 +340,6 @@ with gr.Blocks(title="Manim Render & Audio Tool") as demo:
336
  with gr.Row():
337
  with gr.Column():
338
  video_input_audio_tab = gr.Video(label="Input Video (MP4)")
339
- # For the API, this audio component will accept base64 data
340
  audio_input_audio_tab = gr.Audio(label="Input Audio", type="filepath")
341
  merge_audio_btn = gr.Button("Merge Audio", variant="primary")
342
  with gr.Column():
 
203
  def build_atempo_filter(factor):
204
  """Builds a chained atempo filter for FFmpeg to handle extreme speed changes."""
205
  filters = []
 
206
  while factor > 100.0:
207
  filters.append("atempo=100.0"); factor /= 100.0
208
  while factor < 0.5:
 
216
  if not data_obj or 'data' not in data_obj:
217
  return None
218
 
 
219
  header, encoded_data = data_obj['data'].split(",", 1)
220
  file_extension = header.split('/')[1].split(';')[0]
 
221
  decoded_data = base64.b64decode(encoded_data)
222
 
223
  with tempfile.NamedTemporaryFile(delete=False, suffix=f".{file_extension}") as tmp_file:
 
233
  temp_files_to_clean = []
234
 
235
  try:
 
236
  if isinstance(video_input, str) and os.path.exists(video_input):
237
  video_path = video_input
 
238
  elif isinstance(video_input, dict):
239
  print("API call detected: Decoding video from base64.", flush=True)
240
  video_path = decode_base64_to_tempfile(video_input)
 
247
  audio_path = decode_base64_to_tempfile(audio_input)
248
  if audio_path: temp_files_to_clean.append(audio_path)
249
 
 
250
  if not video_path or not audio_path:
251
  return None, "Error: Missing video or audio file. Please provide both."
252
 
 
259
  if video_duration == 0:
260
  return None, "Error: Input video has zero duration."
261
 
 
262
  speed_factor = audio_duration / video_duration
263
  atempo_filter = build_atempo_filter(speed_factor)
264
 
 
289
  return output_path, "✅ Audio merged successfully!"
290
 
291
  finally:
 
292
  print(f"Cleaning up {len(temp_files_to_clean)} temporary files...", flush=True)
293
  for f in temp_files_to_clean:
294
  try:
 
300
  # 3. Gradio Interface
301
  # ---------------------------------------------------------
302
 
303
+ # --- THIS IS THE FIX ---
304
+ # Define the default code before it is used in the UI.
305
+ DEFAULT_CODE = """from manim import *
306
+
307
+ class GenScene(Scene):
308
+ def construct(self):
309
+ c = Circle(color=BLUE, fill_opacity=0.5)
310
+ self.play(Create(c))
311
+ self.wait(1)
312
+ """
313
+
314
  with gr.Blocks(title="Manim Render & Audio Tool") as demo:
315
  with gr.Tab("🎬 Manim Video Renderer"):
316
  with gr.Row():
317
  with gr.Column(scale=1):
318
+ # The 'value' parameter now has a defined variable to reference.
319
  code_input = gr.Code(label="Python Code", language="python", value=DEFAULT_CODE, visible=True)
320
  orientation_opt = gr.Radio(choices=["Landscape (16:9)", "Portrait (9:16)"], value="Portrait (9:16)", label="Orientation", visible=True)
321
  quality_opt = gr.Dropdown(choices=["Preview (360p)", "480p", "720p", "1080p", "4k"], value="Preview (360p)", label="Quality", visible=True)
 
340
  with gr.Row():
341
  with gr.Column():
342
  video_input_audio_tab = gr.Video(label="Input Video (MP4)")
 
343
  audio_input_audio_tab = gr.Audio(label="Input Audio", type="filepath")
344
  merge_audio_btn = gr.Button("Merge Audio", variant="primary")
345
  with gr.Column():