如何解决 MoviePy 使用大量内存的问题?
How can I address large memory usage by MoviePy?
我正在尝试使用 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()
如果我没理解错的话,你想使用不同的图像作为视频的帧。
在这种情况下,您应该使用 ImageSequenceClip()
(它在库中,但尚未在网络文档中,请参阅 here for the doc)。
基本上,你只要写
clip = ImageSequenceClip("some/directory/", fps=10)
clip.write_videofile("result.mp4")
并且它会以alpha-numerical顺序读取目录中的图像,同时在内存中一次只保留一帧。
当我这样做时,您还可以向 ImageSequenceClip 提供文件名列表或 numpy 数组列表。
请注意,如果您只是想将图像转换成视频,而不是添加标题或与另一个视频合成等其他花哨的东西,那么您可以直接使用 ffmpeg 来完成。根据记忆,命令应该是:
ffmpeg -i *_tile.png -r 10 -o result.mp4
我正在尝试使用 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()
如果我没理解错的话,你想使用不同的图像作为视频的帧。
在这种情况下,您应该使用 ImageSequenceClip()
(它在库中,但尚未在网络文档中,请参阅 here for the doc)。
基本上,你只要写
clip = ImageSequenceClip("some/directory/", fps=10)
clip.write_videofile("result.mp4")
并且它会以alpha-numerical顺序读取目录中的图像,同时在内存中一次只保留一帧。
当我这样做时,您还可以向 ImageSequenceClip 提供文件名列表或 numpy 数组列表。
请注意,如果您只是想将图像转换成视频,而不是添加标题或与另一个视频合成等其他花哨的东西,那么您可以直接使用 ffmpeg 来完成。根据记忆,命令应该是:
ffmpeg -i *_tile.png -r 10 -o result.mp4