Hug0endob commited on
Commit
c04d70f
·
verified ·
1 Parent(s): 310a3db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -59
app.py CHANGED
@@ -159,6 +159,9 @@ def convert_to_jpeg_bytes(img_bytes: bytes, base_h: int = 480) -> bytes:
159
  except UnidentifiedImageError:
160
  print(f"Warning: convert_to_jpeg_bytes received unidentifiable image data.")
161
  return b"" # Return empty bytes if data is not an identifiable image
 
 
 
162
 
163
  try:
164
  if getattr(img, "is_animated", False): # Handles animated GIFs by taking first frame
@@ -524,7 +527,7 @@ def _convert_video_for_preview_if_needed(path: str) -> str:
524
  _temp_preview_files_to_delete.remove(out_path)
525
  try: os.remove(out_path)
526
  except Exception: pass
527
- return path
528
 
529
  # --- Preview Generation Logic ---
530
  def _get_playable_preview_path_from_raw(src_url: str, raw_bytes: bytes, is_image_hint: bool, is_video_hint: bool) -> str:
@@ -536,50 +539,62 @@ def _get_playable_preview_path_from_raw(src_url: str, raw_bytes: bytes, is_image
536
  print(f"Error: No raw bytes provided for preview generation of {src_url}.")
537
  return ""
538
 
539
- if is_video_hint: # Use the passed hint
540
- temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
541
- if not temp_raw_video_path: return "" # Handle if _temp_file failed
542
- playable_path = _convert_video_for_preview_if_needed(temp_raw_video_path)
543
 
544
- # If conversion created a *new* temp path, and the original raw video path
545
- # is no longer needed (and different), remove the raw path's tracking.
546
- if playable_path != temp_raw_video_path and temp_raw_video_path in _temp_preview_files_to_delete:
547
- _temp_preview_files_to_delete.remove(temp_raw_video_path)
548
- try: os.remove(temp_raw_video_path)
549
- except Exception: pass
550
- return playable_path
551
- elif is_image_hint: # Use the passed hint
552
- jpeg_bytes = convert_to_jpeg_bytes(raw_bytes, base_h=1024)
553
- if not jpeg_bytes: # Handle if convert_to_jpeg_bytes failed
554
- print(f"Warning: Could not convert image bytes for {src_url} to JPEG.")
555
- return ""
556
- return _temp_file(jpeg_bytes, suffix=".jpg")
557
- else:
558
- # Fallback if hints are unclear, try image first, then video
559
  try:
560
  # Attempt to open as image
561
- img_bytes_io = BytesIO(raw_bytes)
562
- img = Image.open(img_bytes_io)
563
- img.verify() # Checks if it's a valid image without loading all pixels
564
- img_bytes_io.seek(0) # Reset stream position after verify
565
- jpeg_bytes = convert_to_jpeg_bytes(img_bytes_io.read(), base_h=1024)
566
- if jpeg_bytes: # If conversion yielded bytes, create temp file
567
- return _temp_file(jpeg_bytes, suffix=".jpg")
568
- else: # If convert_to_jpeg_bytes failed even after verify
569
- raise UnidentifiedImageError("Could not convert verified image to JPEG.") # Re-raise to fall to video path
570
  except UnidentifiedImageError:
571
- # If not an image, assume it's a video for preview purposes
572
- print(f"Warning: Unknown media type for {src_url}, falling back to video preview attempt.")
573
- temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
574
- if not temp_raw_video_path: return "" # If _temp_file returns empty due to empty raw_bytes
575
- playable_path = _convert_video_for_preview_if_needed(temp_raw_video_path)
576
- return playable_path
577
- except Exception as e: # Catch other potential PIL/IO errors during image check
578
  print(f"Warning: Generic error during image check for {src_url}: {e}. Falling back to video preview attempt.")
579
- temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
580
- if not temp_raw_video_path: return ""
581
- playable_path = _convert_video_for_preview_if_needed(temp_raw_video_path)
582
- return playable_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
 
584
 
585
  def _fetch_with_retries_bytes(src: str, timeout: int = 15, max_retries: int = 3) -> bytes:
@@ -822,44 +837,56 @@ def create_demo():
822
  if not raw_bytes:
823
  return "error", "Failed to download media bytes.", "", []
824
 
825
- # Check for image type with PIL if initial determination was uncertain
826
- if not is_img_worker and not is_vid_worker:
 
 
 
 
 
827
  try:
 
828
  Image.open(BytesIO(raw_bytes)).verify()
829
- is_img_worker = True
830
- except Exception:
831
- pass # Not an image, proceed to video or generic fallback
 
 
 
 
 
 
 
 
 
 
832
 
833
  # --- Video Processing Path ---
834
- if is_vid_worker:
835
  temp_media_file_for_analysis = _temp_file(raw_bytes, suffix=ext_from_src(url) or ".mp4")
836
  if not temp_media_file_for_analysis: # Handle if _temp_file failed
837
  return "error", "Failed to create temporary video file for analysis.", "", []
838
- generated_main_preview_path = _get_playable_preview_path_from_raw(url, raw_bytes, is_img_worker, is_vid_worker)
839
-
840
  progress(0.25, desc="Running full‑video analysis")
841
  result_text, generated_screenshot_paths = analyze_video_cohesive(client, temp_media_file_for_analysis, prompt, progress=progress)
842
 
843
  # --- Image Processing Path ---
844
- elif is_img_worker:
845
- generated_main_preview_path = _get_playable_preview_path_from_raw(url, raw_bytes, is_img_worker, is_vid_worker)
846
-
847
  progress(0.20, desc="Running image analysis")
848
  result_text = analyze_image_structured(client, raw_bytes, prompt, progress=progress)
849
  # No screenshots for images
850
 
851
- # --- Unknown Media Type (Fallback to Video) ---
852
  else:
853
- # If after all checks, it's still unknown, treat as video by default for analysis.
854
- print(f"Warning: Could not definitively determine media type for {url}. Attempting video analysis.")
 
855
  temp_media_file_for_analysis = _temp_file(raw_bytes, suffix=ext_from_src(url) or ".mp4")
856
- if not temp_media_file_for_analysis: # Handle if _temp_file failed
857
- return "error", "Failed to create temporary video file for analysis (unknown type fallback).", "", []
858
- # Even though type is 'unknown', we'll hint as video for preview creation if it's not an image
859
- generated_main_preview_path = _get_playable_preview_path_from_raw(url, raw_bytes, False, True)
860
- progress(0.25, desc="Running video analysis (fallback for unknown type)")
861
  result_text, generated_screenshot_paths = analyze_video_cohesive(client, temp_media_file_for_analysis, prompt, progress=progress)
862
 
 
863
  status = "done" if not (isinstance(result_text, str) and result_text.lower().startswith("error")) else "error"
864
 
865
  return status, result_text, generated_main_preview_path, generated_screenshot_paths
 
159
  except UnidentifiedImageError:
160
  print(f"Warning: convert_to_jpeg_bytes received unidentifiable image data.")
161
  return b"" # Return empty bytes if data is not an identifiable image
162
+ except Exception as e:
163
+ print(f"Warning: Error opening image for JPEG conversion: {e}")
164
+ return b""
165
 
166
  try:
167
  if getattr(img, "is_animated", False): # Handles animated GIFs by taking first frame
 
527
  _temp_preview_files_to_delete.remove(out_path)
528
  try: os.remove(out_path)
529
  except Exception: pass
530
+ return path
531
 
532
  # --- Preview Generation Logic ---
533
  def _get_playable_preview_path_from_raw(src_url: str, raw_bytes: bytes, is_image_hint: bool, is_video_hint: bool) -> str:
 
539
  print(f"Error: No raw bytes provided for preview generation of {src_url}.")
540
  return ""
541
 
542
+ # Determine media type (prioritizing hints, then byte analysis)
543
+ is_actually_image = False
544
+ is_actually_video = False
 
545
 
546
+ if is_image_hint:
547
+ is_actually_image = True
548
+ elif is_video_hint:
549
+ is_actually_video = True
550
+ else: # If hints are not definitive, try to determine from bytes
 
 
 
 
 
 
 
 
 
 
551
  try:
552
  # Attempt to open as image
553
+ # We don't need to load the whole image, just verify format.
554
+ Image.open(BytesIO(raw_bytes)).verify()
555
+ is_actually_image = True
 
 
 
 
 
 
556
  except UnidentifiedImageError:
557
+ # Not an identifiable image by PIL, assume video
558
+ is_actually_video = True
559
+ except Exception as e:
560
+ # Other PIL errors, assume video as a fallback for preview
 
 
 
561
  print(f"Warning: Generic error during image check for {src_url}: {e}. Falling back to video preview attempt.")
562
+ is_actually_video = True
563
+
564
+ # --- Attempt Image Preview ---
565
+ if is_actually_image:
566
+ jpeg_bytes = convert_to_jpeg_bytes(raw_bytes, base_h=1024)
567
+ if jpeg_bytes:
568
+ return _temp_file(jpeg_bytes, suffix=".jpg")
569
+ else:
570
+ # If image conversion fails, even if it seemed like an image, fall back to video
571
+ print(f"Warning: Could not convert image bytes for {src_url} to JPEG. Attempting video fallback.")
572
+ is_actually_image = False # Clear image flag
573
+ is_actually_video = True # Set video flag for next block
574
+
575
+ # --- Attempt Video Preview ---
576
+ if is_actually_video:
577
+ # Create a temporary file for the raw video bytes first
578
+ temp_raw_video_path = _temp_file(raw_bytes, suffix=ext_from_src(src_url) or ".mp4")
579
+ if not temp_raw_video_path:
580
+ print(f"Error: Failed to create temporary raw video file for {src_url}.")
581
+ return ""
582
+
583
+ playable_path = _convert_video_for_preview_if_needed(temp_raw_video_path)
584
+
585
+ # If _convert_video_for_preview_if_needed created a new file,
586
+ # the original temp_raw_video_path is no longer needed. Remove it from tracking
587
+ # and delete it if it's no longer the returned playable_path.
588
+ if playable_path != temp_raw_video_path and os.path.exists(temp_raw_video_path):
589
+ if temp_raw_video_path in _temp_preview_files_to_delete:
590
+ _temp_preview_files_to_delete.remove(temp_raw_video_path)
591
+ try: os.remove(temp_raw_video_path)
592
+ except Exception as e: print(f"Error during cleanup of intermediate raw video temp file {temp_raw_video_path}: {e}")
593
+
594
+ return playable_path
595
+
596
+ print(f"Error: No playable preview path generated for {src_url}.")
597
+ return ""
598
 
599
 
600
  def _fetch_with_retries_bytes(src: str, timeout: int = 15, max_retries: int = 3) -> bytes:
 
837
  if not raw_bytes:
838
  return "error", "Failed to download media bytes.", "", []
839
 
840
+ # Determine type more definitively using raw bytes
841
+ # This step is now more robustly handled inside _get_playable_preview_path_from_raw itself for preview,
842
+ # but we need it here for deciding analysis path (image model vs. video model)
843
+ is_actually_image_for_analysis = is_img_worker
844
+ is_actually_video_for_analysis = is_vid_worker
845
+
846
+ if not is_actually_image_for_analysis and not is_actually_video_for_analysis:
847
  try:
848
+ # Attempt to open as image
849
  Image.open(BytesIO(raw_bytes)).verify()
850
+ is_actually_image_for_analysis = True
851
+ except UnidentifiedImageError:
852
+ is_actually_video_for_analysis = True # Not an image, assume video
853
+ except Exception as e:
854
+ print(f"Warning: Could not definitively determine media type for {url} based on bytes: {e}. Attempting video analysis.")
855
+ is_actually_video_for_analysis = True # Generic error, fallback to video
856
+
857
+ # Get playable preview path (this internally handles image/video decision and conversion for preview)
858
+ generated_main_preview_path = _get_playable_preview_path_from_raw(url, raw_bytes, is_actually_image_for_analysis, is_actually_video_for_analysis)
859
+ if not generated_main_preview_path:
860
+ print(f"Error: Could not generate main preview for analysis: {url}") # Log this specific failure point
861
+ return "error", "Could not generate a playable preview for display.", "", []
862
+
863
 
864
  # --- Video Processing Path ---
865
+ if is_actually_video_for_analysis:
866
  temp_media_file_for_analysis = _temp_file(raw_bytes, suffix=ext_from_src(url) or ".mp4")
867
  if not temp_media_file_for_analysis: # Handle if _temp_file failed
868
  return "error", "Failed to create temporary video file for analysis.", "", []
 
 
869
  progress(0.25, desc="Running full‑video analysis")
870
  result_text, generated_screenshot_paths = analyze_video_cohesive(client, temp_media_file_for_analysis, prompt, progress=progress)
871
 
872
  # --- Image Processing Path ---
873
+ elif is_actually_image_for_analysis:
 
 
874
  progress(0.20, desc="Running image analysis")
875
  result_text = analyze_image_structured(client, raw_bytes, prompt, progress=progress)
876
  # No screenshots for images
877
 
878
+ # --- Fallback if still no clear analysis path (should be rare with refined logic) ---
879
  else:
880
+ # This block should ideally not be reached if previous type determination is robust.
881
+ # As a final fallback, treat as video for analysis.
882
+ print(f"Warning: No definitive analysis type determined for {url} after all checks. Attempting video analysis fallback.")
883
  temp_media_file_for_analysis = _temp_file(raw_bytes, suffix=ext_from_src(url) or ".mp4")
884
+ if not temp_media_file_for_analysis:
885
+ return "error", "Failed to create temporary video file for final analysis fallback.", "", []
886
+ progress(0.25, desc="Running video analysis (final fallback for unknown type)")
 
 
887
  result_text, generated_screenshot_paths = analyze_video_cohesive(client, temp_media_file_for_analysis, prompt, progress=progress)
888
 
889
+
890
  status = "done" if not (isinstance(result_text, str) and result_text.lower().startswith("error")) else "error"
891
 
892
  return status, result_text, generated_main_preview_path, generated_screenshot_paths