Can you “stream” images to ffmpeg to construct a video, instead of saving them to disk?

前端 未结 2 657
离开以前
离开以前 2020-11-28 02:37

My work recently involves programmatically making videos. In python, the typical workflow looks something like this:

import subprocess, Image, ImageDraw

for         


        
相关标签:
2条回答
  • 2020-11-28 02:51

    Ok I got it working. thanks to LordNeckbeard suggestion to use image2pipe. I had to use jpg encoding instead of png because image2pipe with png doesn't work on my verision of ffmpeg. The first script is essentially the same as your question's code except I implemented a simple image creation that just creates images going from black to red. I also added some code to time the execution.

    serial execution

    import subprocess, Image
    
    fps, duration = 24, 100
    for i in range(fps * duration):
        im = Image.new("RGB", (300, 300), (i, 1, 1))
        im.save("%07d.jpg" % i)
    subprocess.call(["ffmpeg","-y","-r",str(fps),"-i", "%07d.jpg","-vcodec","mpeg4", "-qscale","5", "-r", str(fps), "video.avi"])
    

    parallel execution (with no images saved to disk)

    import Image
    from subprocess import Popen, PIPE
    
    fps, duration = 24, 100
    p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '24', '-i', '-', '-vcodec', 'mpeg4', '-qscale', '5', '-r', '24', 'video.avi'], stdin=PIPE)
    for i in range(fps * duration):
        im = Image.new("RGB", (300, 300), (i, 1, 1))
        im.save(p.stdin, 'JPEG')
    p.stdin.close()
    p.wait()
    

    the results are interesting, I ran each script 3 times to compare performance: serial:

    12.9062321186
    12.8965060711
    12.9360799789
    

    parallel:

    8.67797684669
    8.57139396667
    8.38926696777
    

    So it seems the parallel version is faster about 1.5 times faster.

    0 讨论(0)
  • 2020-11-28 03:01

    imageio supports this directly. It uses FFMPEG and the Video Acceleration API, making it very fast:

    import imageio
    
    writer = imageio.get_writer('video.avi', fps=fps)
    for i in range(frames_per_second * video_duration_seconds):
        img = createFrame(i)
        writer.append_data(img)
    writer.close()
    
    0 讨论(0)
提交回复
热议问题