|
|
import cv2 |
|
|
import os |
|
|
import glob |
|
|
import shutil |
|
|
import subprocess |
|
|
|
|
|
def extract_frames(video_path, output_folder, overwrite=True): |
|
|
|
|
|
if overwrite and os.path.exists(output_folder): |
|
|
shutil.rmtree(output_folder) |
|
|
os.makedirs(output_folder, exist_ok=True) |
|
|
|
|
|
|
|
|
output_pattern = os.path.join(output_folder, "%d.jpg") |
|
|
command = [ |
|
|
"ffmpeg", "-i", video_path, |
|
|
"-q:v", "2", |
|
|
output_pattern |
|
|
] |
|
|
subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
|
|
print(f"β
Extracted frames to: {output_folder}") |
|
|
|
|
|
def extract_frames_old(video_path, output_folder): |
|
|
|
|
|
if os.path.exists(output_folder): |
|
|
for f in glob.glob(os.path.join(output_folder, "*")): |
|
|
os.remove(f) |
|
|
else: |
|
|
os.makedirs(output_folder) |
|
|
|
|
|
cap = cv2.VideoCapture(video_path) |
|
|
frame_id = 0 |
|
|
|
|
|
while True: |
|
|
ret, frame = cap.read() |
|
|
if not ret: |
|
|
break |
|
|
|
|
|
frame_path = os.path.join(output_folder, f"{frame_id}.jpg") |
|
|
cv2.imwrite(frame_path, frame) |
|
|
frame_id += 1 |
|
|
|
|
|
cap.release() |
|
|
print(f"β
Extracted {frame_id} frames to: {output_folder}") |
|
|
|
|
|
|
|
|
def recombine_frames_(video_path, frames_folder, output_video=None): |
|
|
|
|
|
if output_video is None: |
|
|
base, ext = os.path.splitext(video_path) |
|
|
output_video = f"{base}_anonymised.mp4" |
|
|
|
|
|
|
|
|
cap = cv2.VideoCapture(video_path) |
|
|
fps = cap.get(cv2.CAP_PROP_FPS) |
|
|
cap.release() |
|
|
|
|
|
|
|
|
frame_paths = sorted(glob.glob(os.path.join(frames_folder, "*.jpg")), key=lambda x: int(os.path.basename(x).split('.')[0])) |
|
|
|
|
|
if not frame_paths: |
|
|
print("β No frames found to recombine.") |
|
|
return |
|
|
|
|
|
|
|
|
frame_sample = cv2.imread(frame_paths[0]) |
|
|
height, width = frame_sample.shape[:2] |
|
|
|
|
|
|
|
|
fourcc = cv2.VideoWriter_fourcc(*'mp4v') |
|
|
out = cv2.VideoWriter(output_video, fourcc, fps, (width, height)) |
|
|
|
|
|
for frame_path in frame_paths: |
|
|
frame = cv2.imread(frame_path) |
|
|
out.write(frame) |
|
|
|
|
|
out.release() |
|
|
print(f"β
Video saved to: {output_video}") |
|
|
|
|
|
def recombine_frames(video_path, frames_folder, output_video=None, temp_video_path="temp_video_no_audio.mp4"): |
|
|
""" |
|
|
Recombines frames into a video and adds back the original audio using ffmpeg. |
|
|
""" |
|
|
if output_video is None: |
|
|
base, ext = os.path.splitext(video_path) |
|
|
output_video = f"{base}_anonymised.mp4" |
|
|
|
|
|
|
|
|
cap = cv2.VideoCapture(video_path) |
|
|
fps = cap.get(cv2.CAP_PROP_FPS) |
|
|
cap.release() |
|
|
|
|
|
|
|
|
frame_paths = sorted( |
|
|
glob.glob(os.path.join(frames_folder, "*.jpg")), |
|
|
key=lambda x: int(os.path.splitext(os.path.basename(x))[0]) |
|
|
) |
|
|
|
|
|
if not frame_paths: |
|
|
print("β No frames found to recombine.") |
|
|
return |
|
|
|
|
|
|
|
|
sample_frame = cv2.imread(frame_paths[0]) |
|
|
height, width = sample_frame.shape[:2] |
|
|
|
|
|
|
|
|
fourcc = cv2.VideoWriter_fourcc(*'mp4v') |
|
|
out = cv2.VideoWriter(temp_video_path, fourcc, fps, (width, height)) |
|
|
for frame_path in frame_paths: |
|
|
frame = cv2.imread(frame_path) |
|
|
out.write(frame) |
|
|
out.release() |
|
|
|
|
|
|
|
|
ffmpeg_command = [ |
|
|
"ffmpeg", |
|
|
"-y", |
|
|
"-i", temp_video_path, |
|
|
"-i", video_path, |
|
|
"-c:v", "copy", |
|
|
"-map", "0:v:0", |
|
|
"-map", "1:a:0?", |
|
|
"-shortest", |
|
|
output_video |
|
|
] |
|
|
subprocess.run(ffmpeg_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
|
|
|
|
|
|
|
|
|
|
print(f"β
Final video with audio saved to: {output_video}") |
|
|
|
|
|
if __name__ == "__main__": |
|
|
input_video = "/Users/sophiemaw/Downloads/CONFIDENTIAL DO NOT SHARE Edna & Paul 29.10.10 Part 2 00.12.46.531.mov" |
|
|
output_folder = 'frames' |
|
|
extract_frames(input_video,output_folder) |
|
|
|