File size: 2,578 Bytes
e354383 f696f85 88a25be f696f85 7e6ea8d f696f85 e354383 f696f85 e354383 f696f85 7e6ea8d f696f85 7e6ea8d f696f85 7e6ea8d f696f85 e354383 f696f85 e354383 f696f85 88a25be f696f85 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import cv2
import os
import shutil
import time
def extract_frames(video_path, frames_dir, quality=95):
"""Extract frames as high-quality JPGs (better quality + smaller than PNG)."""
os.makedirs(frames_dir, exist_ok=True)
existing = [f for f in os.listdir(frames_dir) if f.startswith("frame_") and f.endswith(".jpg")]
last_idx = max([int(f.split("_")[1].split(".")[0]) for f in existing]) if existing else -1
cap = cv2.VideoCapture(video_path)
frame_paths = []
idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
frame_path = os.path.join(frames_dir, f"frame_{idx:05d}.jpg")
if idx > last_idx:
# High quality JPG
cv2.imwrite(frame_path, frame, [int(cv2.IMWRITE_JPEG_QUALITY), quality])
frame_paths.append(frame_path)
idx += 1
cap.release()
return frame_paths
def frames_to_video(frames_dir, output_video_path, fps, use_ffmpeg=True, crf=17):
"""
Prefer ffmpeg for much better quality and optional hardware encoding.
Falls back to OpenCV if ffmpeg fails.
"""
frames = sorted([
os.path.join(frames_dir, f)
for f in os.listdir(frames_dir)
if f.endswith('.jpg') and f.startswith("swapped_")
])
if not frames:
print("No swapped frames found.")
return
if use_ffmpeg:
# Create a temporary file list for ffmpeg
list_file = os.path.join(frames_dir, "frames.txt")
with open(list_file, "w") as f:
for fp in frames:
f.write(f"file '{os.path.abspath(fp)}'\n")
# High quality + try NVENC if available on A100
cmd = [
"ffmpeg", "-y",
"-f", "concat", "-safe", "0",
"-r", str(fps),
"-i", list_file,
"-c:v", "libx264", # change to h264_nvenc if your Space supports it
"-preset", "slow",
"-crf", str(crf),
"-pix_fmt", "yuv420p",
output_video_path
]
try:
import subprocess
subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
os.remove(list_file)
return
except Exception as e:
print(f"ffmpeg failed ({e}), falling back to OpenCV")
# Fallback
first = cv2.imread(frames[0])
h, w = first.shape[:2]
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_path, fourcc, fps, (w, h))
for fp in frames:
out.write(cv2.imread(fp))
out.release() |