2

I'm trying to get the list of indexes for all I-frames in a video in Python (and later save a portion of them as JPEG). Right now, I can traverse all frames using FFProbe in terminal, and see which one is I-frame:

ffprobe -select_streams v -show_frames -show_entries frame=pict_type -of csv 18s.mp4

which gives me something like this:

frame,I
frame,B
frame,P
frame,B
frame,P
frame,B

But how can I do that in Python (I'm in Windows) and get a list of all their indexes?

Tina J
  • 3,411
  • 8
  • 39
  • 93
  • python can "all out" and execute ffprobe. See also https://stackoverflow.com/questions/7708373/get-ffmpeg-information-in-friendly-way – rogerdpack Aug 02 '18 at 21:53

2 Answers2

1

You could have FFmpeg just output the i frames as JPG. And use a python wrapper to trigger this command.

This will output all the i frames as JPG images.

ffmpeg -i 2.flv -vf "select=eq(pict_type\,I)" -vsync vfr frame-%02d.jpg

Credit to this comment a similar superuser.com question. https://superuser.com/questions/669716/how-to-extract-all-key-frames-from-a-video-clip#comment1184347_669733

Hope that helps. Cheers.

Ian

iangetz
  • 437
  • 2
  • 9
1

Getting insights from here, I was able to do it with ffprobe:

def iframes():
    if not os.path.exists(iframe_path):
        os.mkdir(iframe_path)
    command = 'ffprobe -v error -show_entries frame=pict_type -of default=noprint_wrappers=1'.split()
    out = subprocess.check_output(command + [filename]).decode()
    f_types = out.replace('pict_type=','').split()
    frame_types = zip(range(len(f_types)), f_types)
    i_frames = [x[0] for x in frame_types if x[1]=='I']
    if i_frames:
        cap = cv2.VideoCapture(filename)
        for frame_no in i_frames:
            cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no)
            ret, frame = cap.read()
            outname = iframe_path+'i_frame_'+str(frame_no)+'.jpg'
            cv2.imwrite(outname, frame)
        cap.release()
        print("I-Frame selection Done!!")


if __name__ == '__main__':
    iframes()
Tina J
  • 3,411
  • 8
  • 39
  • 93