refactor(main.py): simplify seek logic, update imports and print statements; update pyproject.toml to include ruff as a dependency

This commit is contained in:
2025-09-07 23:09:54 +02:00
parent 366de8e796
commit 8a266303a5
3 changed files with 42 additions and 63 deletions

View File

@@ -4,7 +4,7 @@ import cv2
import argparse
import numpy as np
from pathlib import Path
from typing import Optional, Tuple, List
from typing import List
import time
import re
import json
@@ -402,7 +402,7 @@ class VideoEditor:
self.cap.set(cv2.CAP_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY)
break
self.cap.release()
except:
except Exception:
continue
if not self.cap or not self.cap.isOpened():
@@ -427,11 +427,11 @@ class VideoEditor:
# Performance warning for known problematic cases
if codec in ['H264', 'H.264', 'AVC1', 'avc1'] and self.total_frames > 10000:
print(f" Warning: Large H.264 video detected - seeking may be slow")
print(" Warning: Large H.264 video detected - seeking may be slow")
if self.frame_width * self.frame_height > 1920 * 1080:
print(f" Warning: High resolution video - decoding may be slow")
print(" Warning: High resolution video - decoding may be slow")
if self.fps > 60:
print(f" Warning: High framerate video - may impact playback smoothness")
print(" Warning: High framerate video - may impact playback smoothness")
# Reset playback state for new media
self.current_frame = 0
@@ -500,55 +500,6 @@ class VideoEditor:
self.current_frame = target_frame
self.load_current_frame()
def seek_video_smart(self, frames_delta: int):
"""Seek using keyframe jumping for large jumps"""
target_frame = max(
0, min(self.current_frame + frames_delta, self.total_frames - 1)
)
# For small jumps, use regular seeking
if abs(frames_delta) <= 10:
self.current_frame = target_frame
self.load_current_frame()
return
# For larger jumps, use keyframe seeking
# Jump to nearest keyframe first, then seek forward
keyframe_interval = self._detect_keyframe_interval()
nearest_keyframe = (target_frame // keyframe_interval) * keyframe_interval
# Seek to keyframe first
self.cap.set(cv2.CAP_PROP_POS_FRAMES, nearest_keyframe)
self.current_frame = nearest_keyframe
# Then seek forward to target frame
frames_to_seek = target_frame - nearest_keyframe
for _ in range(frames_to_seek):
ret, frame = self.cap.read()
if not ret:
break
self.current_frame += 1
self.current_display_frame = frame if 'frame' in locals() else None
def _detect_keyframe_interval(self):
"""Detect the keyframe interval for the current video"""
# Try to get keyframe interval from video properties
try:
# Some backends support keyframe interval detection
keyframe_interval = self.cap.get(cv2.CAP_PROP_FRAME_COUNT) / self.cap.get(cv2.CAP_PROP_FPS)
if keyframe_interval > 0:
return int(keyframe_interval)
except:
pass
# Fallback: estimate based on video characteristics
if self.fps >= 60:
return 60 # High FPS videos often have keyframes every 60 frames
elif self.fps >= 30:
return 30 # Standard videos have keyframes every 30 frames
else:
return 15 # Lower FPS videos have keyframes every 15 frames
def seek_video_with_modifier(
self, direction: int, shift_pressed: bool, ctrl_pressed: bool
@@ -556,13 +507,12 @@ class VideoEditor:
"""Seek video with different frame counts based on modifiers"""
if ctrl_pressed:
frames = direction * 60 # Ctrl: 60 frames
self.seek_video_smart(frames)
elif shift_pressed:
frames = direction * 10 # Shift: 10 frames
self.seek_video_smart(frames)
else:
frames = direction * 1 # Default: 1 frame
self.seek_video(frames)
self.seek_video(frames)
def start_auto_repeat_seek(self, key: int, direction: int, shift_pressed: bool, ctrl_pressed: bool):
"""Start auto-repeat seeking for a held key"""
@@ -1296,7 +1246,6 @@ class VideoEditor:
# Handle crop selection (Shift + click and drag)
if flags & cv2.EVENT_FLAG_SHIFTKEY:
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
if event == cv2.EVENT_LBUTTONDOWN:
self.crop_selecting = True
@@ -1888,7 +1837,6 @@ class VideoEditor:
# Get modifier key states
window_title = "Image Editor" if self.is_image_mode else "Video Editor"
modifiers = cv2.getWindowProperty(window_title, cv2.WND_PROP_AUTOSIZE)
# Note: OpenCV doesn't provide direct access to modifier keys in waitKey
# We'll handle this through special key combinations
@@ -2008,7 +1956,7 @@ class VideoEditor:
temp_fd, temp_path = tempfile.mkstemp(suffix=self.video_path.suffix, dir=temp_dir)
os.close(temp_fd) # Close the file descriptor, we just need the path
print(f"Rendering to temporary file first...")
print("Rendering to temporary file first...")
success = self.render_video(temp_path)
if success:
@@ -2092,9 +2040,9 @@ def main():
try:
args = parser.parse_args()
except SystemExit as e:
except SystemExit:
# If launched from context menu without arguments, this might fail
input(f"Argument parsing failed. Press Enter to exit...")
input("Argument parsing failed. Press Enter to exit...")
return
if not os.path.exists(args.media):