I need to use ffmpeg / avconv to transfer jpg frames to a Python PIL (Pillow) image object using gst as an intermediary *. I searched everywhere for this answer without much luck. I think I'm close, but I'm stuck. Using Python 2.7
My ideal pipeline launched from python looks like this:
- ffmpeg / avconv (as h264 video)
- Pipes β
- gst-streamer (frames are divided into jpg)
- Pipes β
- Pil Image Object
I have the first few steps under control as a single command that writes .jpg to disk as fast as the hardware allows.
This command looks something like this:
command = [ "ffmpeg", "-f video4linux2", "-r 30", "-video_size 1280x720", "-pixel_format 'uyvy422'", "-i /dev/video0", "-vf fps=30", "-f H264", "-vcodec libx264", "-preset ultrafast", "pipe:1 -", "|", # Pipe to GST "gst-launch-1.0 fdsrc !", "video/x-h264,framerate=30/1,stream-format=byte-stream !", "decodebin ! videorate ! video/x-raw,framerate=30/1 !", "videoconvert !", "jpegenc quality=55 !", "multifilesink location=" + Utils.live_sync_path + "live_%04d.jpg" ]
This will successfully write frames to disk if they are started using popen or os.system.
But instead of writing frames to disk, I want to capture the output in my subprocess channel and read the frames as they are written in the file buffer, which can then be read by PIL.
Something like that:
import subprocess as sp import shlex import StringIO clean_cmd = shlex.split(" ".join(command)) pipe = sp.Popen(clean_cmd, stdout = sp.PIPE, bufsize=10**8) while pipe: raw = pipe.stdout.read() buff = StringIO.StringIO() buff.write(raw) buff.seek(0) # Open or do something clever... im = Image.open(buff) im.show() pipe.flush()
This code does not work - I'm not even sure I can use the while pipe in this way. I am new to using buffers and piping this way.
Iβm not sure how I would know that the image was recorded in the handset or when the βnextβ image was read.
Any help would be greatly appreciated in understanding how to read images from a pipe, not to disk.
- This is ultimately the Raspberry Pi 3 pipeline, and to increase the frame rate I cannot (A) read / write to / from the disc or (B) use the frame capture method - unlike launching the H246 video directly from the camera chip.