Remove a bunch of cringe from grader

This commit is contained in:
2025-09-04 15:32:07 +02:00
parent 22bba12d7e
commit 31240dabf9

196
main.py
View File

@@ -295,47 +295,6 @@ class MediaGrader:
merged.append(tuple(new_region)) merged.append(tuple(new_region))
self.watched_regions[file_path] = merged self.watched_regions[file_path] = merged
def find_largest_unwatched_region(self):
"""Find the largest unwatched region in the current video"""
if not self.is_video(self.media_files[self.current_index]):
return None
current_file = str(self.media_files[self.current_index])
watched = self.watched_regions.get(current_file, [])
if not watched:
# No regions watched yet, return the beginning
return (0, self.total_frames // 4)
# Sort watched regions by start frame
watched.sort(key=lambda x: x[0])
# Find gaps between watched regions
gaps = []
# Gap before first watched region
if watched[0][0] > 0:
gaps.append((0, watched[0][0]))
# Gaps between watched regions
for i in range(len(watched) - 1):
gap_start = watched[i][1]
gap_end = watched[i + 1][0]
if gap_end > gap_start:
gaps.append((gap_start, gap_end))
# Gap after last watched region
if watched[-1][1] < self.total_frames:
gaps.append((watched[-1][1], self.total_frames))
if not gaps:
# Everything watched, return None
return None
# Return the largest gap
largest_gap = max(gaps, key=lambda x: x[1] - x[0])
return largest_gap
def get_sample_points(self): def get_sample_points(self):
"""Get standardized sample points for video navigation""" """Get standardized sample points for video navigation"""
segments = 8 # Divide video into 8 segments for sampling segments = 8 # Divide video into 8 segments for sampling
@@ -489,36 +448,6 @@ class MediaGrader:
print(f"Bisected forwards to frame {midpoint} ({percentage:.1f}% through video)") print(f"Bisected forwards to frame {midpoint} ({percentage:.1f}% through video)")
return True return True
def undo_jump(self):
"""Undo the last L jump by returning to previous position"""
if not self.is_video(self.media_files[self.current_index]):
return False
current_file = str(self.media_files[self.current_index])
if current_file not in self.jump_history or not self.jump_history[current_file]:
print("No jump history to undo. Use L first to establish jump points.")
return False
# Get the last position before the most recent jump
if len(self.jump_history[current_file]) < 1:
print("No previous position to return to.")
return False
# Remove the current position from history and get the previous one
previous_position = self.jump_history[current_file].pop()
# Jump back to previous position
self.current_cap.set(cv2.CAP_PROP_POS_FRAMES, previous_position)
self.load_current_frame()
# Update last jump position for bisection reference
self.last_jump_position[current_file] = previous_position
percentage = (previous_position / self.total_frames) * 100
print(f"Undid jump: returned to frame {previous_position} ({percentage:.1f}% through video)")
return True
def toggle_multi_segment_mode(self): def toggle_multi_segment_mode(self):
"""Toggle between single and multi-segment video mode""" """Toggle between single and multi-segment video mode"""
if not self.is_video(self.media_files[self.current_index]): if not self.is_video(self.media_files[self.current_index]):
@@ -544,125 +473,12 @@ class MediaGrader:
print(f"Timeline {'visible' if self.timeline_visible else 'hidden'}") print(f"Timeline {'visible' if self.timeline_visible else 'hidden'}")
return True return True
def load_segment_frame_fast(self, segment_index, start_frame, shared_cap): def setup_segment_captures(self):
"""Load a single segment frame using a shared capture (much faster)"""
segment_start_time = time.time()
try:
# Time the seek operation
seek_start = time.time()
shared_cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
seek_time = (time.time() - seek_start) * 1000
# Time the frame read
read_start = time.time()
ret, frame = shared_cap.read()
read_time = (time.time() - read_start) * 1000
total_time = (time.time() - segment_start_time) * 1000
print(f"Segment {segment_index}: Total={total_time:.1f}ms (Seek={seek_time:.1f}ms, Read={read_time:.1f}ms)")
if ret:
return segment_index, frame.copy(), start_frame # Copy frame since we'll reuse the capture
else:
return segment_index, None, start_frame
except Exception as e:
error_time = (time.time() - segment_start_time) * 1000
print(f"Segment {segment_index}: ERROR in {error_time:.1f}ms: {e}")
return segment_index, None, start_frame
def setup_segment_captures_blazing_fast(self):
"""BLAZING FAST: Sample frames at intervals without any seeking (10-50ms total)"""
if not self.is_video(self.media_files[self.current_index]): if not self.is_video(self.media_files[self.current_index]):
return return
start_time = time.time() start_time = time.time()
print(f"Setting up {self.segment_count} segments with BLAZING FAST method...") print(f"Setting up {self.segment_count} segments...")
# Clean up existing segment captures
self.cleanup_segment_captures()
current_file = self.media_files[self.current_index]
# Initialize arrays
self.segment_caps = [None] * self.segment_count
self.segment_frames = [None] * self.segment_count
self.segment_positions = [0] * self.segment_count # We'll update these as we sample
# BLAZING FAST METHOD: Sample frames at even intervals without seeking
load_start = time.time()
print("Sampling frames at regular intervals (NO SEEKING)...")
shared_cap_start = time.time()
shared_cap = cv2.VideoCapture(str(current_file))
shared_cap_create_time = (time.time() - shared_cap_start) * 1000
print(f"Capture creation: {shared_cap_create_time:.1f}ms")
if shared_cap.isOpened():
frames_start = time.time()
# Calculate sampling interval
sample_interval = max(1, self.total_frames // (self.segment_count * 2)) # Sample more frequently than needed
print(f"Sampling every {sample_interval} frames from {self.total_frames} total frames")
current_frame = 0
segment_index = 0
segments_filled = 0
sample_start = time.time()
while segments_filled < self.segment_count:
ret, frame = shared_cap.read()
if not ret:
break
# Check if this frame should be used for a segment
if segment_index < self.segment_count:
target_frame_for_segment = int((segment_index / max(1, self.segment_count - 1)) * (self.total_frames - 1))
# If we're close enough to the target frame, use this frame
if abs(current_frame - target_frame_for_segment) <= sample_interval:
self.segment_frames[segment_index] = frame.copy()
self.segment_positions[segment_index] = current_frame
print(f"Segment {segment_index}: Frame {current_frame} (target was {target_frame_for_segment})")
segment_index += 1
segments_filled += 1
current_frame += 1
# Skip frames to speed up sampling if we have many frames
if sample_interval > 1:
for _ in range(sample_interval - 1):
ret, _ = shared_cap.read()
if not ret:
break
current_frame += 1
if not ret:
break
sample_time = (time.time() - sample_start) * 1000
frames_time = (time.time() - frames_start) * 1000
print(f"Frame sampling: {sample_time:.1f}ms for {segments_filled} segments")
print(f"Total frame loading: {frames_time:.1f}ms")
shared_cap.release()
else:
print("Failed to create shared capture!")
total_time = time.time() - start_time
print(f"BLAZING FAST Total setup time: {total_time * 1000:.1f}ms")
# Report success
successful_segments = sum(1 for frame in self.segment_frames if frame is not None)
print(f"Successfully sampled {successful_segments}/{self.segment_count} segments")
def setup_segment_captures_lightning_fast(self):
"""LIGHTNING FAST: Use intelligent skipping to get segments in minimal time"""
if not self.is_video(self.media_files[self.current_index]):
return
start_time = time.time()
print(f"Setting up {self.segment_count} segments with LIGHTNING FAST method...")
# Clean up existing segment captures # Clean up existing segment captures
self.cleanup_segment_captures() self.cleanup_segment_captures()
@@ -680,9 +496,7 @@ class MediaGrader:
start_frame = int(position_ratio * (self.total_frames - 1)) start_frame = int(position_ratio * (self.total_frames - 1))
self.segment_positions.append(start_frame) self.segment_positions.append(start_frame)
# LIGHTNING FAST: Smart skipping strategy
load_start = time.time() load_start = time.time()
print("Using SMART SKIPPING strategy...")
shared_cap_start = time.time() shared_cap_start = time.time()
shared_cap = cv2.VideoCapture(str(current_file)) shared_cap = cv2.VideoCapture(str(current_file))
@@ -742,16 +556,12 @@ class MediaGrader:
print("Failed to create shared capture!") print("Failed to create shared capture!")
total_time = time.time() - start_time total_time = time.time() - start_time
print(f"LIGHTNING FAST Total setup time: {total_time * 1000:.1f}ms") print(f"Total setup time: {total_time * 1000:.1f}ms")
# Report success # Report success
successful_segments = sum(1 for frame in self.segment_frames if frame is not None) successful_segments = sum(1 for frame in self.segment_frames if frame is not None)
print(f"Successfully approximated {successful_segments}/{self.segment_count} segments") print(f"Successfully approximated {successful_segments}/{self.segment_count} segments")
def setup_segment_captures(self):
"""Use the lightning fast approximation method for maximum speed"""
self.setup_segment_captures_lightning_fast()
def cleanup_segment_captures(self): def cleanup_segment_captures(self):
"""Clean up all segment video captures""" """Clean up all segment video captures"""
for cap in self.segment_caps: for cap in self.segment_caps: