diff --git a/croppa/main.py b/croppa/main.py index d87a4bd..fd195f9 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -83,9 +83,6 @@ class VideoEditor: else: raise ValueError(f"Path does not exist: {path}") - # Initialize with first video - self._load_video(self.video_files[0]) - # Mouse and keyboard interaction self.mouse_dragging = False self.timeline_rect = None @@ -157,6 +154,12 @@ class VideoEditor: self.cached_frame_number = None self.cached_transform_hash = None + # Initialize with first video + self._load_video(self.video_files[0]) + + # Load saved state after all attributes are initialized + self.load_state() + def _get_state_file_path(self) -> Path: """Get the state file path for the current media file""" if not hasattr(self, 'video_path') or not self.video_path: @@ -245,20 +248,6 @@ class VideoEditor: if 'cut_end_frame' in state: self.cut_end_frame = state['cut_end_frame'] print(f"Loaded cut_end_frame: {self.cut_end_frame}") - - # Validate cut markers against current video length - if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames: - print(f"DEBUG: cut_start_frame {self.cut_start_frame} is beyond video length {self.total_frames}, clearing") - self.cut_start_frame = None - if self.cut_end_frame is not None and self.cut_end_frame >= self.total_frames: - print(f"DEBUG: cut_end_frame {self.cut_end_frame} is beyond video length {self.total_frames}, clearing") - self.cut_end_frame = None - - # Calculate and show marker positions on timeline - if self.cut_start_frame is not None and self.cut_end_frame is not None: - start_progress = self.cut_start_frame / max(1, self.total_frames - 1) - end_progress = self.cut_end_frame / max(1, self.total_frames - 1) - print(f"Markers will be drawn at: Start {start_progress:.4f} ({self.cut_start_frame}/{self.total_frames}), End {end_progress:.4f} ({self.cut_end_frame}/{self.total_frames})") if 'looping_between_markers' in state: self.looping_between_markers = state['looping_between_markers'] print(f"Loaded looping_between_markers: {self.looping_between_markers}") @@ -275,6 +264,20 @@ class VideoEditor: self.is_playing = state['is_playing'] print(f"Loaded is_playing: {self.is_playing}") + # Validate cut markers against current video length + if self.cut_start_frame is not None and self.cut_start_frame >= self.total_frames: + print(f"DEBUG: cut_start_frame {self.cut_start_frame} is beyond video length {self.total_frames}, clearing") + self.cut_start_frame = None + if self.cut_end_frame is not None and self.cut_end_frame >= self.total_frames: + print(f"DEBUG: cut_end_frame {self.cut_end_frame} is beyond video length {self.total_frames}, clearing") + self.cut_end_frame = None + + # Calculate and show marker positions on timeline + if self.cut_start_frame is not None and self.cut_end_frame is not None: + start_progress = self.cut_start_frame / max(1, self.total_frames - 1) + end_progress = self.cut_end_frame / max(1, self.total_frames - 1) + print(f"Markers will be drawn at: Start {start_progress:.4f} ({self.cut_start_frame}/{self.total_frames}), End {end_progress:.4f} ({self.cut_end_frame}/{self.total_frames})") + # Validate and clamp values self.current_frame = max(0, min(self.current_frame, getattr(self, 'total_frames', 1) - 1)) self.zoom_factor = max(self.MIN_ZOOM, min(self.MAX_ZOOM, self.zoom_factor)) @@ -283,6 +286,11 @@ class VideoEditor: self.playback_speed = max(self.MIN_PLAYBACK_SPEED, min(self.MAX_PLAYBACK_SPEED, self.playback_speed)) self.seek_multiplier = max(self.MIN_SEEK_MULTIPLIER, min(self.MAX_SEEK_MULTIPLIER, self.seek_multiplier)) + # Apply loaded settings + self.clear_transformation_cache() + self.load_current_frame() + + print("Successfully loaded and applied all settings from state file") return True except Exception as e: print(f"Error loading state: {e}") @@ -459,30 +467,13 @@ class VideoEditor: if self.fps > 60: print(" Warning: High framerate video - may impact playback smoothness") - # Try to load saved state for this media file first - if self.load_state(): - print("Loaded saved state for this media file") - if self.cut_start_frame is not None: - print(f" Cut start frame: {self.cut_start_frame}") - if self.cut_end_frame is not None: - print(f" Cut end frame: {self.cut_end_frame}") - else: - print("No saved state found for this media file") - # Only reset to defaults if no state was loaded - self.current_frame = 0 - self.is_playing = False if self.is_image_mode else False # Images start paused - self.playback_speed = 1.0 - self.seek_multiplier = 1.0 - self.crop_rect = None - self.crop_history = [] - self.zoom_factor = 1.0 - self.zoom_center = None - self.rotation_angle = 0 - self.brightness = 0 - self.contrast = 1.0 - self.cut_start_frame = None - self.cut_end_frame = None - self.display_offset = [0, 0] + # Set default values for video-specific properties + self.current_frame = 0 + self.is_playing = False if self.is_image_mode else False # Images start paused + self.playback_speed = 1.0 + self.seek_multiplier = 1.0 + self.cut_start_frame = None + self.cut_end_frame = None # Always reset these regardless of state self.current_display_frame = None @@ -672,7 +663,7 @@ class VideoEditor: self.rotation_angle, self.brightness, self.contrast, - self.display_offset + tuple(self.display_offset) )) # Check if we can use cached transformation during auto-repeat seeking