roninpawn / ffmpeg_videostream

FFmpeg-enabled Python Video
9 stars 1 forks source link

extracting i-frames only #4

Open AstonishedByTheLackOfCake opened 1 year ago

AstonishedByTheLackOfCake commented 1 year ago

was wondering if this could be used to quickly extract only the i-frames of a video, preferably by just skipping to the i-frames specifically ignoring everything else

roninpawn commented 1 year ago

I think you'll have better luck with a different ffmpeg interface for Python, rather than trying to adapt my little script to the task.

Ffmpeg can definitely do what you want here -- jumping right to the i-frames, without decoding the ones in between. With a quick search, I found this ffmpeg command:

ffmpeg -skip_frame nokey -i file -vsync 0 -frame_pts true out%d.png

...for generating images from i-frames at the command line. Source here.

The trouble is getting the needed parameters into the Python wrapper's call to ffmpeg. My little script uses a rather limiting ffmpeg wrapper library, to just get'er done. So I imagine it would be a bit of a trick packing the parameters in.

With that said, I recommend looking into deFFcode for your purposes. I'm all but positive it implements the same method my script uses, but its way more flexible and fleshed out. The dev even includes a 'Saving Key-frames as Image" example in the API.

My guess is you can shove all the -skip_frame and -vsync 0 parameters that ffmpeg needs to just pull the i-frames, into deFFcode's ffparams variable... And that'll get ffmpeg to return a pipe of just the decoded i-frame images, without having wasted decode time on the frames between.

Hope this helps!

AstonishedByTheLackOfCake commented 1 year ago

Thanks a bunch, I was already just raw-dogging almost that exact snippet in the cmdline, but would like to avoid saving to disk.

Was also intrigued by your speed advantage in just grabbing raw YUV 4:2:0 data without decoding, as I really only need grayscale data (that I'm compressing further down to just a 64-bit hash anyway) so figured it could be faster if you could potentially just grab the luma component of that and skip or defer any decoding.