Refactor marker navigation in VideoEditor to utilize tracking points
This commit enhances the VideoEditor class by updating the marker navigation methods to focus on tracking points instead of cut markers. The new methods, jump_to_previous_marker and jump_to_next_marker, now utilize a sorted list of frames with tracking points, improving navigation efficiency. Additionally, the documentation has been updated to reflect these changes, providing clearer instructions for users on how to navigate using tracking markers.
This commit is contained in:
@@ -1057,38 +1057,50 @@ class VideoEditor:
|
|||||||
self.current_frame = max(0, min(frame_number, self.total_frames - 1))
|
self.current_frame = max(0, min(frame_number, self.total_frames - 1))
|
||||||
self.load_current_frame()
|
self.load_current_frame()
|
||||||
|
|
||||||
|
def _get_sorted_markers(self):
|
||||||
|
"""Return sorted unique marker list [cut_start_frame, cut_end_frame] as ints within bounds."""
|
||||||
|
markers = []
|
||||||
|
for m in (self.cut_start_frame, self.cut_end_frame):
|
||||||
|
if isinstance(m, int):
|
||||||
|
markers.append(m)
|
||||||
|
if not markers:
|
||||||
|
return []
|
||||||
|
# Clamp and dedupe
|
||||||
|
clamped = set(max(0, min(m, self.total_frames - 1)) for m in markers)
|
||||||
|
return sorted(clamped)
|
||||||
|
|
||||||
def jump_to_previous_marker(self):
|
def jump_to_previous_marker(self):
|
||||||
"""Jump to the previous defined marker (cut_start_frame/cut_end_frame)."""
|
"""Jump to the previous tracking marker (frame with tracking points)."""
|
||||||
if self.is_image_mode:
|
if self.is_image_mode:
|
||||||
return
|
return
|
||||||
markers = [m for m in [self.cut_start_frame, self.cut_end_frame] if isinstance(m, int)]
|
self.stop_auto_repeat_seek()
|
||||||
if not markers:
|
tracking_frames = sorted(k for k, v in self.tracking_points.items() if v)
|
||||||
|
if not tracking_frames:
|
||||||
|
print("DEBUG: No tracking markers; prev jump ignored")
|
||||||
return
|
return
|
||||||
markers = sorted(set(max(0, min(m, self.total_frames - 1)) for m in markers))
|
current = self.current_frame
|
||||||
# Find previous marker relative to current_frame (wrap if needed)
|
candidates = [f for f in tracking_frames if f < current]
|
||||||
prev = None
|
target = candidates[-1] if candidates else tracking_frames[-1]
|
||||||
for m in markers:
|
print(f"DEBUG: Jump prev tracking from {current} -> {target}; tracking_frames={tracking_frames}")
|
||||||
if m < self.current_frame:
|
self.seek_to_frame(target)
|
||||||
prev = m
|
|
||||||
if prev is None:
|
|
||||||
prev = markers[-1]
|
|
||||||
self.seek_to_frame(prev)
|
|
||||||
|
|
||||||
def jump_to_next_marker(self):
|
def jump_to_next_marker(self):
|
||||||
"""Jump to the next defined marker (cut_start_frame/cut_end_frame)."""
|
"""Jump to the next tracking marker (frame with tracking points)."""
|
||||||
if self.is_image_mode:
|
if self.is_image_mode:
|
||||||
return
|
return
|
||||||
markers = [m for m in [self.cut_start_frame, self.cut_end_frame] if isinstance(m, int)]
|
self.stop_auto_repeat_seek()
|
||||||
if not markers:
|
tracking_frames = sorted(k for k, v in self.tracking_points.items() if v)
|
||||||
|
if not tracking_frames:
|
||||||
|
print("DEBUG: No tracking markers; next jump ignored")
|
||||||
return
|
return
|
||||||
markers = sorted(set(max(0, min(m, self.total_frames - 1)) for m in markers))
|
current = self.current_frame
|
||||||
# Find next marker greater than current_frame (wrap if needed)
|
for f in tracking_frames:
|
||||||
for m in markers:
|
if f > current:
|
||||||
if m > self.current_frame:
|
print(f"DEBUG: Jump next tracking from {current} -> {f}; tracking_frames={tracking_frames}")
|
||||||
self.seek_to_frame(m)
|
self.seek_to_frame(f)
|
||||||
return
|
return
|
||||||
# Wrap to first
|
print(f"DEBUG: Jump next tracking wrap from {current} -> {tracking_frames[0]}; tracking_frames={tracking_frames}")
|
||||||
self.seek_to_frame(markers[0])
|
self.seek_to_frame(tracking_frames[0])
|
||||||
|
|
||||||
def advance_frame(self) -> bool:
|
def advance_frame(self) -> bool:
|
||||||
"""Advance to next frame - handles playback speed and marker looping"""
|
"""Advance to next frame - handles playback speed and marker looping"""
|
||||||
|
@@ -57,6 +57,10 @@ That coordinate is to be mapped to the bottom left corner of the original raw un
|
|||||||
- **Crop follows**: Crop area centers on tracked object
|
- **Crop follows**: Crop area centers on tracked object
|
||||||
- **Display** Points are rendered as blue dots per frame, in addition dots are rendered on each frame for each dot on the previous (in red) and next (in green) frame
|
- **Display** Points are rendered as blue dots per frame, in addition dots are rendered on each frame for each dot on the previous (in red) and next (in green) frame
|
||||||
|
|
||||||
|
#### Motion Tracking Navigation
|
||||||
|
- **,**: Jump to previous tracking marker (previous frame that has one or more tracking points). Wrap-around supported.
|
||||||
|
- **.**: Jump to next tracking marker (next frame that has one or more tracking points). Wrap-around supported.
|
||||||
|
|
||||||
### Markers and Looping
|
### Markers and Looping
|
||||||
- **1**: Set cut start marker at current frame
|
- **1**: Set cut start marker at current frame
|
||||||
- **2**: Set cut end marker at current frame
|
- **2**: Set cut end marker at current frame
|
||||||
|
Reference in New Issue
Block a user