【问题标题】:How can I address large memory usage by MoviePy?如何解决 MoviePy 占用大量内存的问题?
【发布时间】:2015-05-02 08:20:05
【问题描述】:

我正在尝试使用 MoviePy 从大量图像中制作视频。该方法适用于少量图像,但对于大量图像,该过程会被终止。在添加了大约 500 个图像时,Python 进程使用了​​大约一半的可用易失性内存。还有很多图片。

我应该如何解决这个问题?我希望处理完成,我不介意处理是否需要更长的时间,但如果我能以某种方式限制内存和 CPU 使用率会很好。使用当前的方法,机器在处理时几乎无法使用。

代码如下:

import os
import time
from   moviepy.editor import *

def ls_files(
    path = "."
    ):
    return([fileName for fileName in os.listdir(path) if os.path.isfile(
        os.path.join(path, fileName)
    )])

def main():

    listOfFiles = ls_files()
    listOfTileImageFiles = [fileName for fileName in listOfFiles \
        if "_tile.png" in fileName
    ]
    numberOfTiledImages = len(listOfTileImageFiles)

    # Create a video clip for each image.
    print("create video")
    videoClips = []
    imageDurations = []
    for imageNumber in range(0, numberOfTiledImages):
        imageFileName = str(imageNumber) + "_tile.png"
        print("add image {fileName}".format(
            fileName = imageFileName
        ))
        imageClip = ImageClip(imageFileName)
        duration  = 0.1
        videoClip = imageClip.set_duration(duration)
        # Determine the image start time by calculating the sum of the durations
        # of all previous images.
        if imageNumber != 0:
            videoStartTime = sum(imageDurations[0:imageNumber])
        else:
            videoStartTime = 0
        videoClip = videoClip.set_start(videoStartTime)
        videoClips.append(videoClip)
        imageDurations.append(duration)
    fullDuration = sum(imageDurations)
    video = concatenate(videoClips)
    video.write_videofile(
        "video.mp4",
        fps         = 30,
        codec       = "mpeg4",
        audio_codec = "libvorbis"
    )

if __name__ == "__main__":
    main()

【问题讨论】:

  • 如果 MoviePy 本质上需要将所有这些剪辑保存在内存中,然后仅在最后写出结果,那么我认为您只能使用不同的库。
  • 我希望它会更聪明,将每个剪辑保留为持续时间和其他一些小信息以及对磁盘上文件的引用,而不是内存中的一大堆帧,但是......这是一个只有几个月大的库,并且仅在 0.2 版上,因此即使设计合理,它也可能无法完美地完成所有工作。
  • @abarnert 它更聪明。请参阅下面的答案。
  • @Zulko:太好了!所以只是文档还不完美。对于 0.2 来说不是一个坏问题。 :)

标签: python memory kill moviepy


【解决方案1】:

如果我理解正确,您想使用不同的图像作为视频的帧。

在这种情况下,您应该使用ImageSequenceClip()(它在库中,但尚未在网络文档中,请参阅here for the doc)。

基本上,你只是写

clip = ImageSequenceClip("some/directory/", fps=10)
clip.write_videofile("result.mp4")

它会按字母数字顺序读取目录中的图像,同时在内存中一次只保留一帧。

当我这样做时,您还可以向 ImageSequenceClip 提供文件名列表或 numpy 数组列表。

请注意,如果您只想将图像转换为视频,而不是像添加标题或与另一个视频合成这样的其他东西,那么您可以直接使用 ffmpeg 来完成。根据记忆,命令应该是:

ffmpeg -i *_tile.png -r 10 -o result.mp4

【讨论】:

  • 啊,太好了。谢谢你的帮助。这很好用。现在内存使用量很小,CPU使用率合理。在内部,它似乎正在做一些类似于你用 ffmpeg 建议的事情。
猜你喜欢
  • 2013-02-07
  • 2020-10-24
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多