feat(main.py): add marker looping functionality and update frame handling
This commit is contained in:
@@ -105,6 +105,9 @@ class VideoEditor:
|
|||||||
self.cut_start_frame = None
|
self.cut_start_frame = None
|
||||||
self.cut_end_frame = None
|
self.cut_end_frame = None
|
||||||
|
|
||||||
|
# Marker looping state
|
||||||
|
self.looping_between_markers = False
|
||||||
|
|
||||||
# Display offset for panning when zoomed
|
# Display offset for panning when zoomed
|
||||||
self.display_offset = [0, 0]
|
self.display_offset = [0, 0]
|
||||||
|
|
||||||
@@ -320,7 +323,15 @@ class VideoEditor:
|
|||||||
frames_to_advance = max(1, int(self.playback_speed))
|
frames_to_advance = max(1, int(self.playback_speed))
|
||||||
|
|
||||||
new_frame = self.current_frame + frames_to_advance
|
new_frame = self.current_frame + frames_to_advance
|
||||||
if new_frame >= self.total_frames:
|
|
||||||
|
# Handle marker looping bounds
|
||||||
|
if self.looping_between_markers and self.cut_start_frame is not None and self.cut_end_frame is not None:
|
||||||
|
if new_frame >= self.cut_end_frame:
|
||||||
|
# Loop back to start marker
|
||||||
|
new_frame = self.cut_start_frame
|
||||||
|
self.current_frame = new_frame
|
||||||
|
return self.load_current_frame()
|
||||||
|
elif new_frame >= self.total_frames:
|
||||||
new_frame = 0 # Loop - this will require a seek
|
new_frame = 0 # Loop - this will require a seek
|
||||||
self.current_frame = new_frame
|
self.current_frame = new_frame
|
||||||
return self.load_current_frame()
|
return self.load_current_frame()
|
||||||
@@ -348,8 +359,18 @@ class VideoEditor:
|
|||||||
# Hit actual end of video
|
# Hit actual end of video
|
||||||
print(f"Reached actual end of video at frame {self.current_frame} (reported: {self.total_frames})")
|
print(f"Reached actual end of video at frame {self.current_frame} (reported: {self.total_frames})")
|
||||||
self.total_frames = self.current_frame
|
self.total_frames = self.current_frame
|
||||||
|
if self.looping_between_markers and self.cut_start_frame is not None:
|
||||||
|
self.current_frame = self.cut_start_frame # Loop back to start marker
|
||||||
|
else:
|
||||||
self.current_frame = 0 # Loop back to start
|
self.current_frame = 0 # Loop back to start
|
||||||
return self.load_current_frame()
|
return self.load_current_frame()
|
||||||
|
|
||||||
|
# Handle marker looping after successful frame load
|
||||||
|
if self.looping_between_markers and self.cut_start_frame is not None and self.cut_end_frame is not None:
|
||||||
|
if self.current_frame >= self.cut_end_frame:
|
||||||
|
self.current_frame = self.cut_start_frame
|
||||||
|
return self.load_current_frame()
|
||||||
|
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def apply_crop_zoom_and_rotation(self, frame):
|
def apply_crop_zoom_and_rotation(self, frame):
|
||||||
@@ -1017,6 +1038,28 @@ class VideoEditor:
|
|||||||
else:
|
else:
|
||||||
self.crop_rect = None
|
self.crop_rect = None
|
||||||
|
|
||||||
|
def toggle_marker_looping(self):
|
||||||
|
"""Toggle looping between cut markers"""
|
||||||
|
# Check if both markers are set
|
||||||
|
if self.cut_start_frame is None or self.cut_end_frame is None:
|
||||||
|
print("Both markers must be set to enable looping. Use '1' and '2' to set markers.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.cut_start_frame >= self.cut_end_frame:
|
||||||
|
print("Invalid marker range - start frame must be before end frame")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.looping_between_markers = not self.looping_between_markers
|
||||||
|
|
||||||
|
if self.looping_between_markers:
|
||||||
|
print(f"Marker looping ENABLED: frames {self.cut_start_frame} - {self.cut_end_frame}")
|
||||||
|
# Jump to start marker when enabling
|
||||||
|
self.seek_to_frame(self.cut_start_frame)
|
||||||
|
else:
|
||||||
|
print("Marker looping DISABLED")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def adjust_crop_size(self, direction: str, expand: bool, amount: int = None):
|
def adjust_crop_size(self, direction: str, expand: bool, amount: int = None):
|
||||||
@@ -1303,6 +1346,7 @@ class VideoEditor:
|
|||||||
print(" Ctrl+Scroll: Zoom in/out")
|
print(" Ctrl+Scroll: Zoom in/out")
|
||||||
print(" 1: Set cut start point")
|
print(" 1: Set cut start point")
|
||||||
print(" 2: Set cut end point")
|
print(" 2: Set cut end point")
|
||||||
|
print(" T: Toggle loop between markers")
|
||||||
if len(self.video_files) > 1:
|
if len(self.video_files) > 1:
|
||||||
print(" N: Next video")
|
print(" N: Next video")
|
||||||
print(" n: Previous video")
|
print(" n: Previous video")
|
||||||
@@ -1398,6 +1442,8 @@ class VideoEditor:
|
|||||||
elif key == 13: # Enter
|
elif key == 13: # Enter
|
||||||
output_name = self._get_next_edited_filename(self.video_path)
|
output_name = self._get_next_edited_filename(self.video_path)
|
||||||
self.render_video(str(self.video_path.parent / output_name))
|
self.render_video(str(self.video_path.parent / output_name))
|
||||||
|
elif key == ord("t"):
|
||||||
|
self.toggle_marker_looping()
|
||||||
|
|
||||||
# Individual direction controls using shift combinations we can detect
|
# Individual direction controls using shift combinations we can detect
|
||||||
elif key == ord("J"): # Shift+i - expand up
|
elif key == ord("J"): # Shift+i - expand up
|
||||||
|
Reference in New Issue
Block a user