Translsis commited on
Commit
e31d0be
·
verified ·
1 Parent(s): 7cae504

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -48
app.py CHANGED
@@ -412,7 +412,7 @@ def process_image_job(job):
412
  'duration': f"{(datetime.now() - start).total_seconds():.2f}s"
413
  }
414
 
415
- @spaces.GPU
416
  def process_video_job(job):
417
  start = datetime.now()
418
  cap = cv2.VideoCapture(job['video'])
@@ -420,16 +420,21 @@ def process_video_job(job):
420
  w, h = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
421
 
422
  frames = []
423
- limit = job.get('frame_limit', 0)
 
 
 
424
  count = 0
425
  while cap.isOpened():
426
  ret, frame = cap.read()
427
- if not ret or (limit > 0 and count >= limit):
428
  break
429
  frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
430
  count += 1
431
  cap.release()
432
 
 
 
433
  session = VID_PROCESSOR.init_video_session(video=frames, inference_device=device, dtype=torch.bfloat16)
434
  session = VID_PROCESSOR.add_text_prompt(inference_session=session, text=job['prompt'])
435
 
@@ -444,6 +449,8 @@ def process_video_job(job):
444
  ]
445
 
446
  total = len(frames)
 
 
447
  for idx, out in enumerate(VID_MODEL.propagate_in_video_iterator(inference_session=session, max_frame_num_to_track=total)):
448
  proc = VID_PROCESSOR.postprocess_outputs(session, out)
449
  orig = Image.fromarray(frames[out.frame_idx])
@@ -480,11 +487,19 @@ def process_video_job(job):
480
  writers[1].write(np.zeros((h, w, 3), dtype=np.uint8))
481
  writers[2].write(orig_bgr)
482
 
483
- processing_results[job['id']]['progress'] = int((idx + 1) / total * 100)
 
 
 
 
 
 
484
 
485
  for w in writers:
486
  w.release()
487
 
 
 
488
  return {
489
  'output_path': out_path,
490
  'mask_video_path': mask_path,
@@ -530,49 +545,65 @@ def process_click_job(job):
530
  # ============ BACKGROUND WORKER ============
531
  def background_worker():
532
  while True:
533
- job = processing_queue.get()
534
- if job is None:
535
- break
536
-
537
- processing_results[job['id']] = {'status': 'processing', 'progress': 0}
538
-
539
  try:
540
- if job['type'] == 'image':
541
- result = process_image_job(job)
542
- elif job['type'] == 'video':
543
- result = process_video_job(job)
544
- elif job['type'] == 'click':
545
- result = process_click_job(job)
546
 
547
- processing_results[job['id']] = {
548
- 'status': 'completed',
549
- 'result': result,
550
- 'progress': 100
551
- }
552
 
553
- save_history({
554
- 'id': job['id'],
555
- 'type': job['type'],
556
- 'prompt': job.get('prompt', 'N/A'),
557
- 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
558
- 'status': 'completed',
559
- **result
560
- })
561
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
562
  except Exception as e:
563
- processing_results[job['id']] = {
564
- 'status': 'error',
565
- 'error': str(e),
566
- 'progress': 0
567
- }
568
- save_history({
569
- 'id': job['id'],
570
- 'type': job['type'],
571
- 'prompt': job.get('prompt', 'N/A'),
572
- 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
573
- 'status': 'error',
574
- 'error': str(e)
575
- })
576
 
577
  threading.Thread(target=background_worker, daemon=True).start()
578
 
@@ -676,9 +707,17 @@ with gr.Blocks(css=custom_css, theme=app_theme, title="SAM3 Segmentation") as de
676
  with gr.Accordion("⚙️ Settings", open=True):
677
  vid_frames = gr.Slider(
678
  10, 500, 60, 10,
679
- label="Max Frames (0 = All frames)",
680
- info="Giới hạn số frame để xử nhanh hơn"
681
  )
 
 
 
 
 
 
 
 
682
 
683
  vid_submit = gr.Button("🚀 Submit Job (Background)", variant="primary", size="lg")
684
  vid_check = gr.Button("🔍 Check Status", variant="secondary")
@@ -1019,9 +1058,15 @@ with gr.Blocks(css=custom_css, theme=app_theme, title="SAM3 Segmentation") as de
1019
  """)
1020
 
1021
  if __name__ == "__main__":
 
 
 
 
 
1022
  demo.launch(
1023
- css=custom_css,
1024
- theme=app_theme,
1025
- ssr_mode=False,
1026
- show_error=True
 
1027
  )
 
412
  'duration': f"{(datetime.now() - start).total_seconds():.2f}s"
413
  }
414
 
415
+ @spaces.GPU(duration=300)
416
  def process_video_job(job):
417
  start = datetime.now()
418
  cap = cv2.VideoCapture(job['video'])
 
420
  w, h = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
421
 
422
  frames = []
423
+ limit = job.get('frame_limit', 60)
424
+ if limit == 0:
425
+ limit = 999999
426
+
427
  count = 0
428
  while cap.isOpened():
429
  ret, frame = cap.read()
430
+ if not ret or count >= limit:
431
  break
432
  frames.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
433
  count += 1
434
  cap.release()
435
 
436
+ print(f"📹 Processing {len(frames)} frames...")
437
+
438
  session = VID_PROCESSOR.init_video_session(video=frames, inference_device=device, dtype=torch.bfloat16)
439
  session = VID_PROCESSOR.add_text_prompt(inference_session=session, text=job['prompt'])
440
 
 
449
  ]
450
 
451
  total = len(frames)
452
+ processed = 0
453
+
454
  for idx, out in enumerate(VID_MODEL.propagate_in_video_iterator(inference_session=session, max_frame_num_to_track=total)):
455
  proc = VID_PROCESSOR.postprocess_outputs(session, out)
456
  orig = Image.fromarray(frames[out.frame_idx])
 
487
  writers[1].write(np.zeros((h, w, 3), dtype=np.uint8))
488
  writers[2].write(orig_bgr)
489
 
490
+ processed += 1
491
+ progress = int((processed / total) * 100)
492
+ processing_results[job['id']]['progress'] = progress
493
+
494
+ # Log progress every 10%
495
+ if progress % 10 == 0:
496
+ print(f"⏳ Video progress: {progress}% ({processed}/{total} frames)")
497
 
498
  for w in writers:
499
  w.release()
500
 
501
+ print(f"✅ Video completed: {len(frames)} frames in {(datetime.now() - start).total_seconds():.2f}s")
502
+
503
  return {
504
  'output_path': out_path,
505
  'mask_video_path': mask_path,
 
545
  # ============ BACKGROUND WORKER ============
546
  def background_worker():
547
  while True:
 
 
 
 
 
 
548
  try:
549
+ job = processing_queue.get()
550
+ if job is None:
551
+ break
 
 
 
552
 
553
+ job_id = job['id']
554
+ job_type = job['type']
 
 
 
555
 
556
+ print(f"🚀 Starting job {job_id[:8]} - Type: {job_type}")
 
 
 
 
 
 
 
557
 
558
+ processing_results[job_id] = {'status': 'processing', 'progress': 0}
559
+
560
+ try:
561
+ if job_type == 'image':
562
+ result = process_image_job(job)
563
+ elif job_type == 'video':
564
+ result = process_video_job(job)
565
+ elif job_type == 'click':
566
+ result = process_click_job(job)
567
+
568
+ processing_results[job_id] = {
569
+ 'status': 'completed',
570
+ 'result': result,
571
+ 'progress': 100
572
+ }
573
+
574
+ print(f"✅ Job {job_id[:8]} completed successfully")
575
+
576
+ save_history({
577
+ 'id': job_id,
578
+ 'type': job_type,
579
+ 'prompt': job.get('prompt', 'N/A'),
580
+ 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
581
+ 'status': 'completed',
582
+ **result
583
+ })
584
+
585
+ except Exception as e:
586
+ print(f"❌ Job {job_id[:8]} failed: {str(e)}")
587
+ import traceback
588
+ traceback.print_exc()
589
+
590
+ processing_results[job_id] = {
591
+ 'status': 'error',
592
+ 'error': str(e),
593
+ 'progress': 0
594
+ }
595
+ save_history({
596
+ 'id': job_id,
597
+ 'type': job_type,
598
+ 'prompt': job.get('prompt', 'N/A'),
599
+ 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
600
+ 'status': 'error',
601
+ 'error': str(e)
602
+ })
603
  except Exception as e:
604
+ print(f"⚠️ Worker error: {e}")
605
+ import traceback
606
+ traceback.print_exc()
 
 
 
 
 
 
 
 
 
 
607
 
608
  threading.Thread(target=background_worker, daemon=True).start()
609
 
 
707
  with gr.Accordion("⚙️ Settings", open=True):
708
  vid_frames = gr.Slider(
709
  10, 500, 60, 10,
710
+ label="Max Frames (Giảm để xử lý nhanh hơn)",
711
+ info="Khuyến nghị: 30-60 frames cho video ngắn, 100-200 cho video dài"
712
  )
713
+
714
+ gr.Markdown("""
715
+ **💡 Lưu ý xử lý video:**
716
+ - Video chạy background, không bị timeout
717
+ - Nhấn "Check Status" để xem progress
718
+ - Video dài sẽ mất nhiều thời gian hơn
719
+ - Giảm số frames nếu muốn xử lý nhanh
720
+ """)
721
 
722
  vid_submit = gr.Button("🚀 Submit Job (Background)", variant="primary", size="lg")
723
  vid_check = gr.Button("🔍 Check Status", variant="secondary")
 
1058
  """)
1059
 
1060
  if __name__ == "__main__":
1061
+ print("🚀 Starting SAM3 Application...")
1062
+ print(f"📁 Output directory: {OUTPUTS_DIR}")
1063
+ print(f"📥 Downloads directory: {DOWNLOADS_DIR}")
1064
+ print(f"📊 History file: {HISTORY_FILE}")
1065
+
1066
  demo.launch(
1067
+ server_name="0.0.0.0",
1068
+ server_port=7860,
1069
+ max_threads=10,
1070
+ show_error=True,
1071
+ share=False
1072
  )