You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MoviePy write_videofile生成视频速度极慢的优化方案求助

MoviePy write_videofile生成视频速度极慢的优化方案求助

我最近在用MoviePy的concatenate_videoclips拼接带图片和文字水印的视频片段,结果导出速度慢到离谱——两个10秒的1080P视频要花2分钟,要是扩展到100个片段生成15分钟视频居然要4小时!我的配置是Intel i7-9700K、32GB内存、RTX2060,按理说完全能胜任,但发现MoviePy全程吃CPU,GPU根本没利用起来。我已经试过threads=12preset="ultrafast"这些参数,一开始速度能上去,但很快就掉到3-5it/s,实在头疼。

先贴一下我的示例代码:

from moviepy.editor import *
from moviepy.config import change_settings

change_settings({"IMAGEMAGICK_BINARY": "D:\\ImageMagick-7.1.1-Q16-HDRI\\magick.exe"})

def create(vid_path: str) -> CompositeVideoClip:
    vid: VideoFileClip = VideoFileClip(vid_path)
    vid = vid.crossfadein(0.8)
    vid = vid.crossfadeout(0.8)

    name_square: ImageClip = ImageClip(".\\square.png")
    name_square = name_square.set_position(('center', 856))
    name_square = name_square.set_duration(vid.duration)
    name_square = name_square.crossfadein(1)
    name_square = name_square.crossfadeout(1)

    name_text: TextClip = TextClip(txt="Hello", fontsize=90, color="gray", font="MomCake")
    name_text = name_text.set_position(("center", 870))
    name_text = name_text.set_duration(vid.duration)
    name_text = name_text.crossfadein(1)
    name_text = name_text.crossfadeout(1)

    comp_clip: CompositeVideoClip = CompositeVideoClip([vid, name_text])
    return comp_clip

final: VideoFileClip = concatenate_videoclips([create("vid1.mp4"), create("vid2.mp4")])
final.write_videofile(f"final_vid.mp4", threads=12, preset="ultrafast", ffmpeg_params=['-b:v','10000k'])

接下来分享几个针对性的优化思路,亲测能有效提升速度:

一、让MoviePy用上GPU加速

你的RTX2060完全没发挥作用,问题出在MoviePy默认用CPU编码,得强制指定GPU加速的编码器:
write_videofileffmpeg_params里加上GPU相关参数,比如用NVENC编码器:

final.write_videofile(
    "final_vid.mp4",
    threads=12,
    preset="ultrafast",
    codec="h264_nvenc",  # 指定NVENC硬件编码
    ffmpeg_params=['-b:v','10000k', '-c:v', 'h264_nvenc']
)

注意要确保你的FFmpeg支持NVENC,要是报错的话,得重新编译或下载带NVENC支持的FFmpeg版本。

二、优化视频片段的预处理逻辑

你的create函数每次都要加载视频、处理水印,重复操作太多,建议:

  • 提前把水印(图片+文字)合成一个单独的CompositeVideoClip,不要每个片段都重复创建
  • 对视频片段尽量用subclip而不是重复加载,减少IO开销
  • VideoFileClip加上target_resolution或者resize统一分辨率,避免后续拼接时动态缩放
    修改后的create函数可以改成这样:
# 提前创建好水印模板,重复使用
watermark_square = ImageClip(".\\square.png").set_position(('center', 856)).crossfadein(1).crossfadeout(1)
watermark_text = TextClip(txt="Hello", fontsize=90, color="gray", font="MomCake").set_position(("center", 870)).crossfadein(1).crossfadeout(1)

def create(vid_path: str) -> CompositeVideoClip:
    vid = VideoFileClip(vid_path).crossfadein(0.8).crossfadeout(0.8)
    # 给水印设置和视频一致的时长,避免重复创建
    square = watermark_square.set_duration(vid.duration)
    text = watermark_text.set_duration(vid.duration)
    return CompositeVideoClip([vid, square, text])

三、调整MoviePy的缓存和内存设置

MoviePy默认的缓存机制可能会拖慢速度,你可以:

  • 设置cache_memory=False,避免把大量帧存进内存导致卡顿
  • temp_audiofiletemp_videofile指定临时文件路径到SSD,提升IO速度
    比如在write_videofile里加上:
final.write_videofile(
    "final_vid.mp4",
    threads=12,
    preset="ultrafast",
    codec="h264_nvenc",
    ffmpeg_params=['-b:v','10000k'],
    cache_memory=False,
    temp_audiofile="temp_audio.m4a",
    temp_videofile="temp_video.mp4"
)

四、替换TextClip为更高效的方案

TextClip依赖ImageMagick,处理速度很慢,要是你的文字内容固定或者变化不大,建议:

  • 提前用PS或其他工具把文字做成图片,直接用ImageClip加载,比动态生成TextClip快很多
  • 如果必须动态生成文字,可以试试PIL.ImageDraw生成图片再转成ImageClip,绕过ImageMagick的开销

五、其他小技巧

  • 关闭不必要的日志输出,用logger=None代替logger=False,减少IO输出
  • 如果不需要音频,直接加audio=False参数,跳过音频编码步骤
  • concatenate_videoclipsmethod="compose"改成method="chain",适合片段格式一致的情况,能减少拼接时的重新编码

希望这些方法能帮你把速度提上去!

备注:内容来源于stack exchange,提问作者PeppersONLY

火山引擎 最新活动