I have this function that basically takes a folder of frames and merges it to form a mp4 video
def frames_to_video(frames_path, fps, job_id, output_folder):
"""
Compiles images from a specified folder into a video file at a given fps.
"""
# Ensure the output folder exists
os.makedirs(output_folder, exist_ok=True)
output_video_path = os.path.join(output_folder, f"{job_id}.mp4")
frame_files = sorted([os.path.join(frames_path, f) for f in os.listdir(frames_path) if f.endswith(('.png', '.jpg', '.jpeg'))])
if not frame_files:
print("No frames found in the specified path.")
return
# Read the first frame to determine the video size
frame = cv2.imread(frame_files[0])
if frame is None:
print("Error reading the first frame.")
return
height, width, _ = frame.shape
size = (width, height)
# Define the codec and create a VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 'mp4v' for .mp4 output
out = cv2.VideoWriter(output_video_path, fourcc, fps, size)
for frame_file in frame_files:
frame = cv2.imread(frame_file)
if frame is None:
print(f"Error reading frame: {frame_file}")
continue
# Write the frame to the video file
out.write(frame)
# Release the VideoWriter object
out.release()
print(f"Video saved to {output_video_path}")
Its seems to save the file correctly, however, VSCode isn't able to preview it (I have MPEG-Preview extension installed), if i download the video to my mac, its viewable. However the problems lies with if i try to stream it using something like FastAPI, its not viewable as well, it loads but isn't playable, its just a media player...
@app.get("/preview/{job_id}")
async def serve_video(job_id: str):
video_path = os.path.join(f"{TEMP_STORAGE}/{job_id}", f"{job_id}.mp4")
if not os.path.exists(video_path):
raise HTTPException(status_code=404, detail="Video not found")
return FileResponse(video_path, media_type="video/mp4")
Not sure if I'm making a mistake somewhere but I've tried quite a few of the suggested solutions, is there an alternative way to merge my frames?