我最近的工作涉及以编程方式制作视频。在python中,典型的工作流程如下所示:
import subprocess, Image, ImageDraw for i in range(frames_per_second * video_duration_seconds): img = createFrame(i) img.save("%07d.png" % i) subprocess.call(["ffmpeg","-y","-r",str(frames_per_second),"-i", "%07d.png","-vcodec","mpeg4", "-qscale","5", "-r", str(frames_per_second), "video.avi"])
此工作流程为视频中的每个帧创建一个图像并将其保存到磁盘。保存所有图像后,将调用ffmpeg从所有图像构建视频。
将映像保存到磁盘(而不是在内存中创建映像)会占用此处的大部分周期,并且似乎没有必要。有什么方法可以执行相同的功能,但不将图像保存到磁盘吗?因此,将调用ffmpeg,然后将图像构建并在构建后立即将其馈送到ffmpeg。
好吧,我知道了。感谢LordNeckbeard建议使用image2pipe。我必须使用jpg编码而不是png,因为带png的image2pipe在我的ffmpeg版本上不起作用。第一个脚本与您的问题的代码基本相同,除了我实现了一个简单的图像创建功能,即仅创建从黑色到红色的图像。我还添加了一些代码来计时执行时间。
串行执行
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"])
并行执行(不将任何图像保存到磁盘)
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()
结果很有趣,我运行了每个脚本3次以比较性能: 串行:
12.9062321186 12.8965060711 12.9360799789
平行:
8.67797684669 8.57139396667 8.38926696777
因此,似乎并行版本的速度要快1.5倍左右。