kkroening / ffmpeg-python

Python bindings for FFmpeg - with complex filtering support
Apache License 2.0
9.94k stars 885 forks source link

How to convert video to multiple images #638

Open patience00 opened 2 years ago

patience00 commented 2 years ago

out, err = ( ffmpeg.input(in_file) .filter('select', 'gte(n,{})'.format(frame_num)) .output('pipe:', vframes=1, format='image2', vcodec='mjpeg') .run(capture_stdout=True) ) can I convert video to multiple images with the method above? and what is the parameter "vframes=1" mean? thank u !

wumingyu12 commented 1 year ago

i has the same problem

patience00 commented 1 year ago

i has the same problem

I found a solution: def video_extract(source_video, to_path, startTime, speed): to_path = to_path +'%05d.jpg' strcmd = 'ffmpeg -ss %d -i "%s" -filter:v "select=not(mod(n\,%d)),setpts=N/(25*TB)" -qscale:v 1 "%s"' % ( startTime, source_video, speed, to_path) print(strcmd) subprocess.call(args=strcmd, shell=True, stdout=sys.stdout, stderr=sys.stderr)

But this method can only screenshot at fixed intervals

05Alston commented 1 year ago

I used a function from the docs

import numpy as np
from PIL import Image

def convert_vid_to_np_arr(video_path):
    probe = ffmpeg.probe(video_path)
    video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
    width = int(video_stream['width'])
    height = int(video_stream['height'])
    out, _ = (
        ffmpeg
        .input(video_path)
        .output('pipe:', format='rawvideo', pix_fmt='rgb24')
        .run(capture_stdout=True)
    )
    video = (
        np
        .frombuffer(out, np.uint8)
        .reshape([-1, height, width, 3])
    )
    return video

out = convert_vid_to_np_arr(path_to_video)
for ind in range(len(out)):
    im = Image.fromarray(out[ind])
    im.save(f'frames/frame{str(ind).zfill(len(str(len(out))))}.jpg')

The above code will get the frames from the source video and store it in the frames folder.