refactor(main.py): consolidate save_state calls to a single method for consistency and improve logging
This commit is contained in:
@@ -145,6 +145,7 @@ class VideoEditor:
|
||||
"""Save current editor state to JSON file"""
|
||||
state_file = self._get_state_file_path()
|
||||
if not state_file:
|
||||
print("No state file path available")
|
||||
return False
|
||||
|
||||
try:
|
||||
@@ -167,6 +168,7 @@ class VideoEditor:
|
||||
|
||||
with open(state_file, 'w') as f:
|
||||
json.dump(state, f, indent=2)
|
||||
print(f"State saved to {state_file}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error saving state: {e}")
|
||||
@@ -486,7 +488,6 @@ class VideoEditor:
|
||||
)
|
||||
self.current_frame = target_frame
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
|
||||
|
||||
def seek_video_with_modifier(
|
||||
@@ -544,7 +545,6 @@ class VideoEditor:
|
||||
"""Seek to specific frame"""
|
||||
self.current_frame = max(0, min(frame_number, self.total_frames - 1))
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
|
||||
def advance_frame(self) -> bool:
|
||||
"""Advance to next frame - optimized to avoid seeking, handles playback speed"""
|
||||
@@ -564,13 +564,11 @@ class VideoEditor:
|
||||
new_frame = self.cut_start_frame
|
||||
self.current_frame = new_frame
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
return True
|
||||
elif new_frame >= self.total_frames:
|
||||
new_frame = 0 # Loop - this will require a seek
|
||||
self.current_frame = new_frame
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
return True
|
||||
|
||||
# For sequential playback at normal speed, just read the next frame without seeking
|
||||
@@ -579,7 +577,6 @@ class VideoEditor:
|
||||
if ret:
|
||||
self.current_frame = new_frame
|
||||
self.current_display_frame = frame
|
||||
self.save_state()
|
||||
return True
|
||||
|
||||
else:
|
||||
@@ -589,7 +586,6 @@ class VideoEditor:
|
||||
self.total_frames = self.current_frame
|
||||
self.current_frame = 0 # Loop back to start
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
return True
|
||||
else:
|
||||
# For speed > 1.0, we need to seek to skip frames
|
||||
@@ -604,7 +600,6 @@ class VideoEditor:
|
||||
else:
|
||||
self.current_frame = 0 # Loop back to start
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
return True
|
||||
|
||||
# Handle marker looping after successful frame load
|
||||
@@ -612,10 +607,8 @@ class VideoEditor:
|
||||
if self.current_frame >= self.cut_end_frame:
|
||||
self.current_frame = self.cut_start_frame
|
||||
self.load_current_frame()
|
||||
self.save_state()
|
||||
return True
|
||||
|
||||
self.save_state()
|
||||
return success
|
||||
|
||||
def apply_crop_zoom_and_rotation(self, frame):
|
||||
@@ -680,7 +673,6 @@ class VideoEditor:
|
||||
def rotate_clockwise(self):
|
||||
"""Rotate video 90 degrees clockwise"""
|
||||
self.rotation_angle = (self.rotation_angle + 90) % 360
|
||||
self.save_state()
|
||||
|
||||
def apply_brightness_contrast(self, frame):
|
||||
"""Apply brightness and contrast adjustments to frame"""
|
||||
@@ -699,12 +691,10 @@ class VideoEditor:
|
||||
def adjust_brightness(self, delta: int):
|
||||
"""Adjust brightness by delta (-100 to 100)"""
|
||||
self.brightness = max(-100, min(100, self.brightness + delta))
|
||||
self.save_state()
|
||||
|
||||
def adjust_contrast(self, delta: float):
|
||||
"""Adjust contrast by delta (0.1 to 3.0)"""
|
||||
self.contrast = max(0.1, min(3.0, self.contrast + delta))
|
||||
self.save_state()
|
||||
|
||||
def show_progress_bar(self, text: str = "Processing..."):
|
||||
"""Show progress bar with given text"""
|
||||
@@ -1234,7 +1224,6 @@ class VideoEditor:
|
||||
# Handle zoom center (Ctrl + click)
|
||||
if flags & cv2.EVENT_FLAG_CTRLKEY and event == cv2.EVENT_LBUTTONDOWN:
|
||||
self.zoom_center = (x, y)
|
||||
self.save_state()
|
||||
|
||||
# Handle scroll wheel for zoom (Ctrl + scroll)
|
||||
if flags & cv2.EVENT_FLAG_CTRLKEY:
|
||||
@@ -1247,7 +1236,6 @@ class VideoEditor:
|
||||
self.zoom_factor = max(
|
||||
self.MIN_ZOOM, self.zoom_factor - self.ZOOM_INCREMENT
|
||||
)
|
||||
self.save_state()
|
||||
|
||||
def set_crop_from_screen_coords(self, screen_rect):
|
||||
"""Convert screen coordinates to video frame coordinates and set crop"""
|
||||
@@ -1367,7 +1355,6 @@ class VideoEditor:
|
||||
if self.crop_rect:
|
||||
self.crop_history.append(self.crop_rect)
|
||||
self.crop_rect = (original_x, original_y, original_w, original_h)
|
||||
self.save_state()
|
||||
|
||||
def seek_to_timeline_position(self, mouse_x, bar_x_start, bar_width):
|
||||
"""Seek to position based on mouse click on timeline"""
|
||||
@@ -1382,7 +1369,6 @@ class VideoEditor:
|
||||
self.crop_rect = self.crop_history.pop()
|
||||
else:
|
||||
self.crop_rect = None
|
||||
self.save_state()
|
||||
|
||||
def toggle_marker_looping(self):
|
||||
"""Toggle looping between cut markers"""
|
||||
@@ -1438,26 +1424,22 @@ class VideoEditor:
|
||||
new_y = max(0, y - amount)
|
||||
new_h = h + (y - new_y)
|
||||
self.crop_rect = (x, new_y, w, new_h)
|
||||
self.save_state()
|
||||
else:
|
||||
# Contract from bottom - decrease height
|
||||
new_h = max(10, h - amount) # Minimum size of 10 pixels
|
||||
self.crop_rect = (x, y, w, new_h)
|
||||
self.save_state()
|
||||
|
||||
elif direction == 'down':
|
||||
if expand:
|
||||
# Expand downward - increase height
|
||||
new_h = min(self.frame_height - y, h + amount)
|
||||
self.crop_rect = (x, y, w, new_h)
|
||||
self.save_state()
|
||||
else:
|
||||
# Contract from top - increase y, decrease height
|
||||
amount = min(amount, h - 10) # Don't make it smaller than 10 pixels
|
||||
new_y = y + amount
|
||||
new_h = h - amount
|
||||
self.crop_rect = (x, new_y, w, new_h)
|
||||
self.save_state()
|
||||
|
||||
elif direction == 'left':
|
||||
if expand:
|
||||
@@ -1465,26 +1447,22 @@ class VideoEditor:
|
||||
new_x = max(0, x - amount)
|
||||
new_w = w + (x - new_x)
|
||||
self.crop_rect = (new_x, y, new_w, h)
|
||||
self.save_state()
|
||||
else:
|
||||
# Contract from right - decrease width
|
||||
new_w = max(10, w - amount) # Minimum size of 10 pixels
|
||||
self.crop_rect = (x, y, new_w, h)
|
||||
self.save_state()
|
||||
|
||||
elif direction == 'right':
|
||||
if expand:
|
||||
# Expand rightward - increase width
|
||||
new_w = min(self.frame_width - x, w + amount)
|
||||
self.crop_rect = (x, y, new_w, h)
|
||||
self.save_state()
|
||||
else:
|
||||
# Contract from left - increase x, decrease width
|
||||
amount = min(amount, w - 10) # Don't make it smaller than 10 pixels
|
||||
new_x = x + amount
|
||||
new_w = w - amount
|
||||
self.crop_rect = (new_x, y, new_w, h)
|
||||
self.save_state()
|
||||
|
||||
def render_video(self, output_path: str):
|
||||
"""Render video or save image with current edits applied"""
|
||||
@@ -1797,13 +1775,13 @@ class VideoEditor:
|
||||
|
||||
if key == ord("q") or key == 27: # ESC
|
||||
self.stop_auto_repeat_seek()
|
||||
self.save_state()
|
||||
break
|
||||
elif key == ord(" "):
|
||||
# Don't allow play/pause for images
|
||||
if not self.is_image_mode:
|
||||
self.stop_auto_repeat_seek() # Stop seeking when toggling play/pause
|
||||
self.is_playing = not self.is_playing
|
||||
self.save_state()
|
||||
elif key == ord("a") or key == ord("A"):
|
||||
# Seeking only for videos
|
||||
if not self.is_image_mode:
|
||||
@@ -1845,14 +1823,12 @@ class VideoEditor:
|
||||
self.playback_speed = min(
|
||||
self.MAX_PLAYBACK_SPEED, self.playback_speed + self.SPEED_INCREMENT
|
||||
)
|
||||
self.save_state()
|
||||
elif key == ord("S"):
|
||||
# Speed control only for videos
|
||||
if not self.is_image_mode:
|
||||
self.playback_speed = max(
|
||||
self.MIN_PLAYBACK_SPEED, self.playback_speed - self.SPEED_INCREMENT
|
||||
)
|
||||
self.save_state()
|
||||
elif key == ord("e") or key == ord("E"):
|
||||
# Brightness adjustment: E (increase), Shift+E (decrease)
|
||||
if key == ord("E"):
|
||||
@@ -1875,19 +1851,16 @@ class VideoEditor:
|
||||
if self.crop_rect:
|
||||
self.crop_history.append(self.crop_rect)
|
||||
self.crop_rect = None
|
||||
self.save_state()
|
||||
elif key == ord("1"):
|
||||
# Cut markers only for videos
|
||||
if not self.is_image_mode:
|
||||
self.cut_start_frame = self.current_frame
|
||||
print(f"Set cut start at frame {self.current_frame}")
|
||||
self.save_state()
|
||||
elif key == ord("2"):
|
||||
# Cut markers only for videos
|
||||
if not self.is_image_mode:
|
||||
self.cut_end_frame = self.current_frame
|
||||
print(f"Set cut end at frame {self.current_frame}")
|
||||
self.save_state()
|
||||
elif key == ord("N"):
|
||||
if len(self.video_files) > 1:
|
||||
self.previous_video()
|
||||
@@ -1939,7 +1912,6 @@ class VideoEditor:
|
||||
# Marker looping only for videos
|
||||
if not self.is_image_mode:
|
||||
self.toggle_marker_looping()
|
||||
self.save_state()
|
||||
|
||||
# Individual direction controls using shift combinations we can detect
|
||||
elif key == ord("J"): # Shift+i - expand up
|
||||
@@ -1974,6 +1946,7 @@ class VideoEditor:
|
||||
if self.is_playing and not self.is_image_mode:
|
||||
self.advance_frame()
|
||||
|
||||
self.save_state()
|
||||
if hasattr(self, 'cap') and self.cap:
|
||||
self.cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
Reference in New Issue
Block a user