2

I want to read a video file and save the frames in python list, something similar like buffer read. I do not want to use opencv (cv2.VideoCapture) or any other library to read the video file. Any lead how can I do it?

Thanks in advance.

MMH
  • 1,676
  • 5
  • 26
  • 43
  • Who ever down voted the question, can you please explain why? – MMH Jul 08 '20 at 05:41
  • 2
    Sorry, asking for library endorsement is off-topic here as it leasds to opinion based answers. Try researching the topic and try some methods you stumble upon, come back if you have a specific questions thats on topic. – Patrick Artner Jul 08 '20 at 05:41
  • 1
    Googeling `python read video without opencv` gives some leads: https://stackoverflow.com/questions/44140354/display-video-on-python-without-opencv and https://scikit-image.org/docs/dev/user_guide/video.html – Patrick Artner Jul 08 '20 at 05:43
  • 1
    Sorry, but I am not looking for any library, I was trying to see if there is any other way except using opencv library and if we can use python to read the frames directly. – MMH Jul 08 '20 at 05:47
  • And about 90s googeling would have given you at least 5 alternatives (see 2nd link abve) ... so ... does your question here show research efford? – Patrick Artner Jul 08 '20 at 05:49

2 Answers2

2

You can use the subprocess module and call ffmpeg. You can use ffmpeg to read and write a huge amount of different video formats.

If you want a more ergonomic interface, you can also use ffmpeg bindings for Python (for example, ffmpeg-python).

def read_frames(path, res):
    """Read numpy arrays of video frames. Path is the file path
       and res is the resolution as a tuple."""
    args = [
        "ffmpeg",
        "-i",
        path,
        "-f",
        "image2pipe",
        "-pix_fmt",
        "rgb24",
        "-vcodec",
        "rawvideo",
        "-",
    ]

    pipe = subprocess.Popen(
        args,
        stdout=subprocess.PIPE,
        stderr=subprocess.DEVNULL,
        bufsize=res[0] * res[1] * 3,
    )

    while pipe.poll() is None:
        frame = pipe.stdout.read(res[0] * res[1] * 3)
        if len(frame) > 0:
            array = np.frombuffer(frame, dtype="uint8")
            yield array.reshape((res[1], res[0], 3))
Leo
  • 1,273
  • 9
  • 14
2

Have you considered using ffmpeg? It's technically a command line tool but can be used with Python, as seen in this post. This also uses the PIL library.

For info on capturing frame-by-frame, check this out.

GLaw1300
  • 195
  • 9