Reputation: 43
I am using ffmpeg to convert a video into images. These images are then processed by my Python program. Originally I used ffmpeg to first save the images to disk, then reading them one by one with Python.
This works fine, but in an effort to speed up the program I am trying to skip the storage step and only work with the images in memory.
I use the following ffmpeg and Python subproccesses command to pipe the output from ffmpeg to Python:
command = "ffmpeg.exe -i ADD\\sg1-original.mp4 -r 1 -f image2pipe pipe:1"
pipe = subprocess.Popen(ffmpeg-command, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
image = Image.new(pipe.communicate()[0])
The image variable can then be used by my program. The problem is that if I send more than 1 image from ffmpeg all the data is stored in this variable. I need a way to separate the images. The only way I can think of is splitting on jpeg markers end of file (0xff, 0xd9). This works, but is unreliable.
What have I missed regarding piping files with subproccesses. Is there a way to only read one file at a time from the pipeline ?
Upvotes: 4
Views: 1908
Reputation: 154494
One solution to this would be to use the ppm format, which has a predictable size:
ffmpeg -i movie.mp4 -r 1 -f image2pipe -vcodec ppm pipe:1
The format is specified here: http://netpbm.sourceforge.net/doc/ppm.html
And looks something like this:
P6 # magic number
640 480 # width height
255 # colors per channel
<data>
Where will be exactly 640 * 480 * 3 bytes (assuming there are 255 or fewer colors per channel).
Note that this is an uncompressed format, so it may potentially take up quite a bit of memory if you read it all at once. You may consider switching your algorithm to:
pipe = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, stderr=sys.stderr)
while True:
chunk = pipe.stdout.read(4096)
if not chunk:
break
# ... process chunk of data ...
Note that the subprocess' stderr
is set to the current process' stderr; this is important because, if we don't, the stderr buffer could fill up (as nothing is reading it) and cause a deadlock.
Upvotes: 2