cv2.VideoWriter_fourcc(*'mp4v') outputs seem to be corrupted

38 Views Asked by At

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?

0

There are 0 best solutions below