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:
@@ -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):
|
||||
|
Reference in New Issue
Block a user