Remove some garbage code
This commit is contained in:
114
croppa/main.py
114
croppa/main.py
@@ -11,7 +11,6 @@ import json
|
||||
import threading
|
||||
import queue
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
class VideoEditor:
|
||||
# Configuration constants
|
||||
@@ -502,49 +501,6 @@ class VideoEditor:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _load_frame_with_ffmpeg(self, frame_number: int) -> bool:
|
||||
"""Load a specific frame using FFmpeg - much faster than OpenCV seeking"""
|
||||
try:
|
||||
# Calculate timestamp
|
||||
timestamp = frame_number / self.fps
|
||||
|
||||
# Use FFmpeg to extract the specific frame
|
||||
cmd = [
|
||||
'ffmpeg', '-y', '-v', 'quiet',
|
||||
'-ss', str(timestamp),
|
||||
'-i', str(self.video_path),
|
||||
'-vframes', '1',
|
||||
'-f', 'image2pipe',
|
||||
'-vcodec', 'png',
|
||||
'-'
|
||||
]
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True)
|
||||
if result.returncode == 0:
|
||||
# Decode the PNG data
|
||||
nparr = np.frombuffer(result.stdout, np.uint8)
|
||||
frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
||||
if frame is not None:
|
||||
self.current_display_frame = frame
|
||||
return True
|
||||
|
||||
# Fallback to OpenCV if FFmpeg fails
|
||||
self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
|
||||
ret, frame = self.cap.read()
|
||||
if ret:
|
||||
self.current_display_frame = frame
|
||||
return True
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"FFmpeg frame loading failed: {e}, falling back to OpenCV")
|
||||
# Fallback to OpenCV
|
||||
self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
|
||||
ret, frame = self.cap.read()
|
||||
if ret:
|
||||
self.current_display_frame = frame
|
||||
return True
|
||||
return False
|
||||
|
||||
def calculate_frame_delay(self) -> int:
|
||||
"""Calculate frame delay in milliseconds based on playback speed"""
|
||||
@@ -1611,11 +1567,7 @@ class VideoEditor:
|
||||
# Send progress update to main thread
|
||||
self.render_progress_queue.put(("init", "Initializing render...", 0.0, 0.0))
|
||||
|
||||
# Create a separate VideoCapture for the render thread to avoid thread safety issues
|
||||
render_cap = cv2.VideoCapture(str(self.video_path))
|
||||
if not render_cap.isOpened():
|
||||
self.render_progress_queue.put(("error", "Could not open video for rendering!", 1.0, 0.0))
|
||||
return False
|
||||
# No need to create VideoCapture since we use FFmpeg directly
|
||||
|
||||
# Determine frame range
|
||||
start_frame = self.cut_start_frame if self.cut_start_frame is not None else 0
|
||||
@@ -1667,9 +1619,8 @@ class VideoEditor:
|
||||
print(f"Render error: {error_msg}")
|
||||
return False
|
||||
finally:
|
||||
# Always clean up the render VideoCapture
|
||||
if render_cap:
|
||||
render_cap.release()
|
||||
# No cleanup needed since we don't create VideoCapture
|
||||
pass
|
||||
|
||||
def update_render_progress(self):
|
||||
"""Process progress updates from the render thread"""
|
||||
@@ -1958,65 +1909,6 @@ class VideoEditor:
|
||||
self.render_progress_queue.put(("error", f"FFmpeg pipe rendering failed: {error_msg}", 1.0, 0.0))
|
||||
return False
|
||||
|
||||
def _render_as_frames(self, output_path: str, start_frame: int, end_frame: int, output_width: int, output_height: int):
|
||||
"""Fallback method to save individual frames when video encoding fails"""
|
||||
try:
|
||||
# Create output directory for frames
|
||||
frames_dir = output_path.replace('.mp4', '_frames').replace('.avi', '_frames')
|
||||
import os
|
||||
os.makedirs(frames_dir, exist_ok=True)
|
||||
|
||||
self.render_progress_queue.put(("progress", "Saving individual frames...", 0.1, 0.0))
|
||||
|
||||
# Create a separate VideoCapture for the render thread
|
||||
render_cap = cv2.VideoCapture(str(self.video_path))
|
||||
if not render_cap.isOpened():
|
||||
self.render_progress_queue.put(("error", "Could not open video for frame extraction!", 1.0, 0.0))
|
||||
return False
|
||||
|
||||
# Seek once to the start frame
|
||||
render_cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
|
||||
|
||||
total_frames = end_frame - start_frame + 1
|
||||
frames_saved = 0
|
||||
|
||||
for frame_idx in range(start_frame, end_frame + 1):
|
||||
# Check for cancellation
|
||||
if self.render_cancelled:
|
||||
render_cap.release()
|
||||
self.render_progress_queue.put(("cancelled", "Frame extraction cancelled", 0.0, 0.0))
|
||||
return False
|
||||
|
||||
# Read frame sequentially
|
||||
ret, frame = render_cap.read()
|
||||
if not ret:
|
||||
break
|
||||
|
||||
# Process frame
|
||||
processed_frame = self._process_frame_for_render(frame, output_width, output_height)
|
||||
if processed_frame is not None:
|
||||
# Save as individual frame
|
||||
frame_filename = f"frame_{frame_idx:06d}.jpg"
|
||||
frame_path = os.path.join(frames_dir, frame_filename)
|
||||
cv2.imwrite(frame_path, processed_frame)
|
||||
frames_saved += 1
|
||||
|
||||
# Update progress
|
||||
if frames_saved % 10 == 0: # Update every 10 frames
|
||||
progress = 0.1 + (0.9 * (frames_saved / total_frames))
|
||||
fps_rate = frames_saved / (time.time() - start_time) if frames_saved > 0 else 0
|
||||
self.render_progress_queue.put(("progress", f"Saving frames: {frames_saved}/{total_frames}", progress, fps_rate))
|
||||
|
||||
render_cap.release()
|
||||
|
||||
self.render_progress_queue.put(("complete", f"Saved {frames_saved} frames to {frames_dir}", 1.0, 0.0))
|
||||
print(f"Saved {frames_saved} individual frames to: {frames_dir}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.render_progress_queue.put(("error", f"Frame extraction failed: {e}", 1.0, 0.0))
|
||||
return False
|
||||
|
||||
def run(self):
|
||||
"""Main editor loop"""
|
||||
if self.is_image_mode:
|
||||
|
Reference in New Issue
Block a user