sourxbhh commited on
Commit
9b0e308
Β·
1 Parent(s): f464d55
Files changed (1) hide show
  1. app.py +212 -211
app.py CHANGED
@@ -294,158 +294,159 @@ def generate_motion_single(
294
  return None, error_msg
295
 
296
 
297
- def generate_motion_batch(
298
- text_file_content: str,
299
- cfg_scale: float,
300
- use_auto_length: bool,
301
- gpu_id: int,
302
- seed: int
303
- ) -> Tuple[List[Optional[str]], str]:
304
- """
305
- Generate motions from a batch of text prompts.
306
- Returns (list_of_video_paths, status_message)
307
- """
308
- # Parse text file
309
- text_prompts = []
310
- for line in text_file_content.strip().split('\n'):
311
- line = line.strip()
312
- if not line:
313
- continue
314
- if '#' in line:
315
- parts = line.split('#')
316
- text = parts[0].strip()
317
- length_str = parts[1].strip() if len(parts) > 1 else 'NA'
318
- else:
319
- text = line
320
- length_str = 'NA'
321
-
322
- if length_str.upper() == 'NA':
323
- motion_length = None if use_auto_length else 120
324
- else:
325
- try:
326
- motion_length = int(length_str)
327
- motion_length = ((motion_length + 2) // 4) * 4
328
- except:
329
- motion_length = None if use_auto_length else 120
330
-
331
- text_prompts.append((text, motion_length))
332
-
333
- if not text_prompts:
334
- return [], "No valid prompts found in file"
335
-
336
- status_msg = f"Processing {len(text_prompts)} prompts...\n"
337
- video_paths = []
338
-
339
- # Create a persistent directory for batch videos (not temp, so Gradio can access them)
340
- # Use a directory that Gradio can serve from
341
- batch_output_dir = pjoin('generation', 'batch_temp')
342
- os.makedirs(batch_output_dir, exist_ok=True)
343
-
344
- # Also ensure the parent directory exists
345
- os.makedirs('generation', exist_ok=True)
346
-
347
- for idx, (text, motion_length) in enumerate(text_prompts):
348
- try:
349
- video_path, gen_msg = generate_motion_single(
350
- text, motion_length, cfg_scale, use_auto_length, gpu_id, seed + idx
351
- )
352
-
353
- # If video was created, copy it to persistent location for batch gallery
354
- if video_path and os.path.exists(video_path):
355
- # Create a unique filename for this batch item
356
- # Get file extension from original path
357
- file_ext = os.path.splitext(video_path)[1] or '.mp4'
358
- batch_video_path = pjoin(batch_output_dir, f'motion_{idx:04d}{file_ext}')
359
-
360
- # Copy file to persistent location
361
- import shutil
362
- try:
363
- shutil.copy2(video_path, batch_video_path)
364
-
365
- # Verify the copied file exists
366
- if os.path.exists(batch_video_path):
367
- # Use relative path for Gradio (works better in HuggingFace Spaces)
368
- # Gradio can serve files from relative paths within the app directory
369
- video_paths.append(batch_video_path)
370
- file_size = os.path.getsize(batch_video_path)
371
- status_msg += f"\n[{idx+1}/{len(text_prompts)}] βœ“ {text[:50]}... - Video saved ({file_size/1024:.1f} KB)"
372
- else:
373
- status_msg += f"\n[{idx+1}/{len(text_prompts)}] ⚠ {text[:50]}... - Video copy failed (file not found after copy)"
374
- video_paths.append(None)
375
- except Exception as copy_error:
376
- status_msg += f"\n[{idx+1}/{len(text_prompts)}] ⚠ {text[:50]}... - Copy error: {str(copy_error)}"
377
- video_paths.append(None)
378
- else:
379
- status_msg += f"\n[{idx+1}/{len(text_prompts)}] ❌ {text[:50]}... - Generation failed (no video path returned)"
380
- video_paths.append(None)
381
-
382
- except Exception as e:
383
- status_msg += f"\n[{idx+1}/{len(text_prompts)}] ❌ Error: {str(e)}"
384
- import traceback
385
- status_msg += f"\n Traceback: {traceback.format_exc()[:200]}"
386
- video_paths.append(None)
387
-
388
- # Filter out None values and verify files exist - Gradio Gallery needs valid paths
389
- valid_video_paths = []
390
- for path in video_paths:
391
- if path is not None:
392
- # Use relative path (Gradio handles these better in cloud environments)
393
- # Verify file exists
394
- if os.path.exists(path):
395
- # Verify it's a video file
396
- if path.lower().endswith(('.mp4', '.gif', '.mov', '.avi')):
397
- # Get file size for debugging
398
- file_size = os.path.getsize(path)
399
- if file_size > 0: # Ensure file is not empty
400
- valid_video_paths.append(path) # Keep relative path
401
- status_msg += f"\n βœ“ Verified: {os.path.basename(path)} ({file_size/1024:.1f} KB)"
402
- else:
403
- status_msg += f"\n ⚠ Empty file: {path}"
404
- else:
405
- status_msg += f"\n ⚠ Skipping non-video file: {path}"
406
- else:
407
- # Try absolute path as fallback
408
- abs_path = os.path.abspath(path)
409
- if os.path.exists(abs_path):
410
- valid_video_paths.append(abs_path)
411
- status_msg += f"\n βœ“ Found via absolute path: {abs_path}"
412
- else:
413
- status_msg += f"\n ⚠ File not found (relative: {path}, absolute: {abs_path})"
414
-
415
- if len(valid_video_paths) == 0:
416
- status_msg += "\n\n❌ No videos were successfully generated for the gallery."
417
- status_msg += "\nπŸ’‘ Check the error messages above for each prompt."
418
- # Return empty list explicitly
419
- return [], status_msg
420
- else:
421
- status_msg += f"\n\nβœ… Successfully generated {len(valid_video_paths)}/{len(text_prompts)} motions."
422
- status_msg += f"\nπŸ“ Videos saved in: {batch_output_dir}"
423
- status_msg += f"\nπŸ“‹ Gallery will display {len(valid_video_paths)} video(s)."
424
-
425
- # Debug: Show first few paths
426
- status_msg += f"\n\n🎬 First few video paths:\n"
427
- for i, p in enumerate(valid_video_paths[:3]):
428
- abs_p = os.path.abspath(p) if not os.path.isabs(p) else p
429
- exists = "βœ“" if os.path.exists(p) else "βœ—"
430
- status_msg += f" {exists} [{i+1}] {p} (exists: {os.path.exists(p)})\n"
431
- if len(valid_video_paths) > 3:
432
- status_msg += f" ... and {len(valid_video_paths) - 3} more\n"
433
-
434
- # Return list of file paths (Gradio Gallery expects list of strings)
435
- # Ensure all paths are valid and accessible
436
- final_paths = []
437
- for p in valid_video_paths:
438
- if os.path.exists(p):
439
- # Normalize path (use forward slashes for cross-platform compatibility)
440
- normalized_path = p.replace('\\', '/')
441
- final_paths.append(normalized_path)
442
- else:
443
- status_msg += f"\n⚠ Warning: Path not found when returning: {p}"
444
-
445
- if len(final_paths) != len(valid_video_paths):
446
- status_msg += f"\n⚠ Some paths were filtered out. Returning {len(final_paths)}/{len(valid_video_paths)} videos."
447
-
448
- return final_paths, status_msg
 
449
 
450
 
451
  # Gradio Interface
@@ -546,65 +547,65 @@ def create_interface():
546
  outputs=[video_output, status_output]
547
  )
548
 
549
- # Batch Generation Tab
550
- with gr.Tab("Batch Generation"):
551
- with gr.Row():
552
- with gr.Column(scale=1):
553
- batch_text_input = gr.Textbox(
554
- label="Text Prompts (one per line, format: text#length or text#NA)",
555
- placeholder="A person is running on a treadmill.#120\nSomeone is doing jumping jacks.#NA",
556
- lines=10,
557
- info="Each line: 'text#length' or 'text#NA' for auto-estimate"
558
- )
559
-
560
- batch_cfg_scale = gr.Slider(
561
- label="CFG Scale",
562
- minimum=1.0,
563
- maximum=10.0,
564
- value=3.0,
565
- step=0.5
566
- )
567
-
568
- batch_use_auto_length = gr.Checkbox(
569
- label="Auto-estimate length for NA",
570
- value=True
571
- )
572
-
573
- batch_gpu_id = gr.Number(
574
- label="GPU ID",
575
- value=0,
576
- precision=0
577
- )
578
-
579
- batch_seed = gr.Number(
580
- label="Random Seed",
581
- value=3407,
582
- precision=0
583
- )
584
-
585
- batch_generate_btn = gr.Button("Generate Batch", variant="primary", size="lg")
586
-
587
- with gr.Column(scale=1):
588
- batch_status_output = gr.Textbox(
589
- label="Batch Status",
590
- lines=15,
591
- interactive=False
592
- )
593
- batch_video_gallery = gr.Gallery(
594
- label="Generated Motions",
595
- show_label=True,
596
- elem_id="gallery",
597
- columns=2,
598
- rows=2,
599
- height="auto",
600
- type="filepath" # Explicitly specify filepath type
601
- )
602
-
603
- batch_generate_btn.click(
604
- fn=generate_motion_batch,
605
- inputs=[batch_text_input, batch_cfg_scale, batch_use_auto_length, batch_gpu_id, batch_seed],
606
- outputs=[batch_video_gallery, batch_status_output]
607
- )
608
 
609
  # Model Management Tab
610
  with gr.Tab("Model Management"):
 
294
  return None, error_msg
295
 
296
 
297
+ # Batch generation feature commented out
298
+ # def generate_motion_batch(
299
+ # text_file_content: str,
300
+ # cfg_scale: float,
301
+ # use_auto_length: bool,
302
+ # gpu_id: int,
303
+ # seed: int
304
+ # ) -> Tuple[List[Optional[str]], str]:
305
+ # """
306
+ # Generate motions from a batch of text prompts.
307
+ # Returns (list_of_video_paths, status_message)
308
+ # """
309
+ # # Parse text file
310
+ # text_prompts = []
311
+ # for line in text_file_content.strip().split('\n'):
312
+ # line = line.strip()
313
+ # if not line:
314
+ # continue
315
+ # if '#' in line:
316
+ # parts = line.split('#')
317
+ # text = parts[0].strip()
318
+ # length_str = parts[1].strip() if len(parts) > 1 else 'NA'
319
+ # else:
320
+ # text = line
321
+ # length_str = 'NA'
322
+ #
323
+ # if length_str.upper() == 'NA':
324
+ # motion_length = None if use_auto_length else 120
325
+ # else:
326
+ # try:
327
+ # motion_length = int(length_str)
328
+ # motion_length = ((motion_length + 2) // 4) * 4
329
+ # except:
330
+ # motion_length = None if use_auto_length else 120
331
+ #
332
+ # text_prompts.append((text, motion_length))
333
+ #
334
+ # if not text_prompts:
335
+ # return [], "No valid prompts found in file"
336
+ #
337
+ # status_msg = f"Processing {len(text_prompts)} prompts...\n"
338
+ # video_paths = []
339
+ #
340
+ # # Create a persistent directory for batch videos (not temp, so Gradio can access them)
341
+ # # Use a directory that Gradio can serve from
342
+ # batch_output_dir = pjoin('generation', 'batch_temp')
343
+ # os.makedirs(batch_output_dir, exist_ok=True)
344
+ #
345
+ # # Also ensure the parent directory exists
346
+ # os.makedirs('generation', exist_ok=True)
347
+ #
348
+ # for idx, (text, motion_length) in enumerate(text_prompts):
349
+ # try:
350
+ # video_path, gen_msg = generate_motion_single(
351
+ # text, motion_length, cfg_scale, use_auto_length, gpu_id, seed + idx
352
+ # )
353
+ #
354
+ # # If video was created, copy it to persistent location for batch gallery
355
+ # if video_path and os.path.exists(video_path):
356
+ # # Create a unique filename for this batch item
357
+ # # Get file extension from original path
358
+ # file_ext = os.path.splitext(video_path)[1] or '.mp4'
359
+ # batch_video_path = pjoin(batch_output_dir, f'motion_{idx:04d}{file_ext}')
360
+ #
361
+ # # Copy file to persistent location
362
+ # import shutil
363
+ # try:
364
+ # shutil.copy2(video_path, batch_video_path)
365
+ #
366
+ # # Verify the copied file exists
367
+ # if os.path.exists(batch_video_path):
368
+ # # Use relative path for Gradio (works better in HuggingFace Spaces)
369
+ # # Gradio can serve files from relative paths within the app directory
370
+ # video_paths.append(batch_video_path)
371
+ # file_size = os.path.getsize(batch_video_path)
372
+ # status_msg += f"\n[{idx+1}/{len(text_prompts)}] βœ“ {text[:50]}... - Video saved ({file_size/1024:.1f} KB)"
373
+ # else:
374
+ # status_msg += f"\n[{idx+1}/{len(text_prompts)}] ⚠ {text[:50]}... - Video copy failed (file not found after copy)"
375
+ # video_paths.append(None)
376
+ # except Exception as copy_error:
377
+ # status_msg += f"\n[{idx+1}/{len(text_prompts)}] ⚠ {text[:50]}... - Copy error: {str(copy_error)}"
378
+ # video_paths.append(None)
379
+ # else:
380
+ # status_msg += f"\n[{idx+1}/{len(text_prompts)}] ❌ {text[:50]}... - Generation failed (no video path returned)"
381
+ # video_paths.append(None)
382
+ #
383
+ # except Exception as e:
384
+ # status_msg += f"\n[{idx+1}/{len(text_prompts)}] ❌ Error: {str(e)}"
385
+ # import traceback
386
+ # status_msg += f"\n Traceback: {traceback.format_exc()[:200]}"
387
+ # video_paths.append(None)
388
+ #
389
+ # # Filter out None values and verify files exist - Gradio Gallery needs valid paths
390
+ # valid_video_paths = []
391
+ # for path in video_paths:
392
+ # if path is not None:
393
+ # # Use relative path (Gradio handles these better in cloud environments)
394
+ # # Verify file exists
395
+ # if os.path.exists(path):
396
+ # # Verify it's a video file
397
+ # if path.lower().endswith(('.mp4', '.gif', '.mov', '.avi')):
398
+ # # Get file size for debugging
399
+ # file_size = os.path.getsize(path)
400
+ # if file_size > 0: # Ensure file is not empty
401
+ # valid_video_paths.append(path) # Keep relative path
402
+ # status_msg += f"\n βœ“ Verified: {os.path.basename(path)} ({file_size/1024:.1f} KB)"
403
+ # else:
404
+ # status_msg += f"\n ⚠ Empty file: {path}"
405
+ # else:
406
+ # status_msg += f"\n ⚠ Skipping non-video file: {path}"
407
+ # else:
408
+ # # Try absolute path as fallback
409
+ # abs_path = os.path.abspath(path)
410
+ # if os.path.exists(abs_path):
411
+ # valid_video_paths.append(abs_path)
412
+ # status_msg += f"\n βœ“ Found via absolute path: {abs_path}"
413
+ # else:
414
+ # status_msg += f"\n ⚠ File not found (relative: {path}, absolute: {abs_path})"
415
+ #
416
+ # if len(valid_video_paths) == 0:
417
+ # status_msg += "\n\n❌ No videos were successfully generated for the gallery."
418
+ # status_msg += "\nπŸ’‘ Check the error messages above for each prompt."
419
+ # # Return empty list explicitly
420
+ # return [], status_msg
421
+ # else:
422
+ # status_msg += f"\n\nβœ… Successfully generated {len(valid_video_paths)}/{len(text_prompts)} motions."
423
+ # status_msg += f"\nπŸ“ Videos saved in: {batch_output_dir}"
424
+ # status_msg += f"\nπŸ“‹ Gallery will display {len(valid_video_paths)} video(s)."
425
+ #
426
+ # # Debug: Show first few paths
427
+ # status_msg += f"\n\n🎬 First few video paths:\n"
428
+ # for i, p in enumerate(valid_video_paths[:3]):
429
+ # abs_p = os.path.abspath(p) if not os.path.isabs(p) else p
430
+ # exists = "βœ“" if os.path.exists(p) else "βœ—"
431
+ # status_msg += f" {exists} [{i+1}] {p} (exists: {os.path.exists(p)})\n"
432
+ # if len(valid_video_paths) > 3:
433
+ # status_msg += f" ... and {len(valid_video_paths) - 3} more\n"
434
+ #
435
+ # # Return list of file paths (Gradio Gallery expects list of strings)
436
+ # # Ensure all paths are valid and accessible
437
+ # final_paths = []
438
+ # for p in valid_video_paths:
439
+ # if os.path.exists(p):
440
+ # # Normalize path (use forward slashes for cross-platform compatibility)
441
+ # normalized_path = p.replace('\\', '/')
442
+ # final_paths.append(normalized_path)
443
+ # else:
444
+ # status_msg += f"\n⚠ Warning: Path not found when returning: {p}"
445
+ #
446
+ # if len(final_paths) != len(valid_video_paths):
447
+ # status_msg += f"\n⚠ Some paths were filtered out. Returning {len(final_paths)}/{len(valid_video_paths)} videos."
448
+ #
449
+ # return final_paths, status_msg
450
 
451
 
452
  # Gradio Interface
 
547
  outputs=[video_output, status_output]
548
  )
549
 
550
+ # Batch Generation Tab - COMMENTED OUT
551
+ # with gr.Tab("Batch Generation"):
552
+ # with gr.Row():
553
+ # with gr.Column(scale=1):
554
+ # batch_text_input = gr.Textbox(
555
+ # label="Text Prompts (one per line, format: text#length or text#NA)",
556
+ # placeholder="A person is running on a treadmill.#120\nSomeone is doing jumping jacks.#NA",
557
+ # lines=10,
558
+ # info="Each line: 'text#length' or 'text#NA' for auto-estimate"
559
+ # )
560
+ #
561
+ # batch_cfg_scale = gr.Slider(
562
+ # label="CFG Scale",
563
+ # minimum=1.0,
564
+ # maximum=10.0,
565
+ # value=3.0,
566
+ # step=0.5
567
+ # )
568
+ #
569
+ # batch_use_auto_length = gr.Checkbox(
570
+ # label="Auto-estimate length for NA",
571
+ # value=True
572
+ # )
573
+ #
574
+ # batch_gpu_id = gr.Number(
575
+ # label="GPU ID",
576
+ # value=0,
577
+ # precision=0
578
+ # )
579
+ #
580
+ # batch_seed = gr.Number(
581
+ # label="Random Seed",
582
+ # value=3407,
583
+ # precision=0
584
+ # )
585
+ #
586
+ # batch_generate_btn = gr.Button("Generate Batch", variant="primary", size="lg")
587
+ #
588
+ # with gr.Column(scale=1):
589
+ # batch_status_output = gr.Textbox(
590
+ # label="Batch Status",
591
+ # lines=15,
592
+ # interactive=False
593
+ # )
594
+ # batch_video_gallery = gr.Gallery(
595
+ # label="Generated Motions",
596
+ # show_label=True,
597
+ # elem_id="gallery",
598
+ # columns=2,
599
+ # rows=2,
600
+ # height="auto",
601
+ # type="filepath" # Explicitly specify filepath type
602
+ # )
603
+ #
604
+ # batch_generate_btn.click(
605
+ # fn=generate_motion_batch,
606
+ # inputs=[batch_text_input, batch_cfg_scale, batch_use_auto_length, batch_gpu_id, batch_seed],
607
+ # outputs=[batch_video_gallery, batch_status_output]
608
+ # )
609
 
610
  # Model Management Tab
611
  with gr.Tab("Model Management"):