找到你要的答案

Q:How can I address large memory usage by MoviePy?

Q:我怎么能解决大内存使用的MoviePy?

I am trying to make a video from a large number of images using MoviePy. The approach works fine for small numbers of images, but the process is killed for large numbers of images. At about 500 images added, the Python process is using all about half of the volatile memory available. There are many more images than that.

How should I address this? I want the processing to complete and I don't mind if the processing takes a bit longer, but it would be good if I could limit the memory and CPU usage in some way. With the current approach, the machine becomes almost unusable while processing.

The code is as follows:

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制作视频。该方法适用于小数量的图像,但这个过程被杀死了大量的图像。在约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()
answer1: 回答1:

If I understood correctly, you want to use the different images as the frames of your video.

In this case you should use ImageSequenceClip() (it's in the library, but not yet in the web docs, see here for the doc).

Basically, you just write

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

And it will read the images in the directory in alpha-numerical order, while keeping only one frame at a time in the memory.

While I am at it, you can also provide a list of filenames or a list of numpy arrays to ImageSequenceClip.

Note that if you just want to transform images into a video, and not anything else fancy like adding titles or compositing with another video, then you can do it directly with ffmpeg. From memory the command should be:

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

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

在这种情况下,你应该使用imagesequenceclip()(这是在图书馆,但没有在Web文档,看到这里的医生)。

基本上,你只是写

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

它将以alpha数值顺序读取目录中的图像,同时在内存中只保存一帧。

而我在这,你也可以提供一个清单的文件名或一个imagesequenceclip NumPy数组列表的。

注意,如果你只想将图像变换到一个视频,不为别的喜欢添加标题或合成与另一个视频,那么你可以直接用ffmpeg。从内存的命令应该是:

ffmpeg -i *_tile.png -r 10 -o result.mp4
python  memory  kill  moviepy