You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python结合MoviePy异步并行编辑多个视频?

使用Python + MoviePy异步并行编辑多个视频

你的代码思路方向是对的,但直接用async/await无法实现真正的并行——因为MoviePy的所有核心API(比如resize、write_videofile)都是同步阻塞的,会卡住asyncio的事件循环,导致视频处理实际上还是串行执行。

下面是修正后的可运行代码,通过asyncio.to_thread将同步的视频处理逻辑放到线程池执行,真正实现并行处理:

import asyncio
from moviepy.editor import VideoFileClip, clips_array
import os

# 请根据实际情况修改以下变量
videos = ["video1.mp4", "video2.mp4", "video3.mp4"]  # 待处理的视频路径列表
chemin_semi_final = "./processed_videos"  # 输出目录
video_random_path = "background_video.mp4"  # 用于拼接的随机视频路径

# 提前加载随机视频,避免重复加载浪费资源
video_random = VideoFileClip(video_random_path)

async def upload():
    # 限制并发数,避免系统资源耗尽(根据CPU/内存调整数值)
    semaphore = asyncio.Semaphore(4)
    
    async def bounded_edit(video_path):
        async with semaphore:
            return await edit(video_random, video_path)
    
    edit_tasks = [bounded_edit(video) for video in videos]
    processed_paths = await asyncio.gather(*edit_tasks)
    print(f"所有视频处理完成,输出路径:{processed_paths}")

async def edit(random_video, video_path):
    # 将同步的视频处理逻辑封装到函数中,交给线程池执行
    def process_single_video():
        # 加载目标视频
        video1 = VideoFileClip(video_path)
        # 调整随机视频宽度匹配目标视频
        video2 = random_video.resize(width=video1.size[0])
        # 垂直拼接两个视频
        combined_clip = clips_array([[video1], [video2]])
        # 居中裁剪到720x1280尺寸
        crop_x = (combined_clip.w - 720) // 2
        crop_y = (combined_clip.h - 1280) // 2
        final_clip = combined_clip.crop(crop_x, crop_y, crop_x + 720, crop_y + 1280)
        
        # 生成输出文件名(兼容Windows/Linux路径)
        video_filename = os.path.basename(video_path)
        output_path = os.path.join(chemin_semi_final, video_filename)
        
        # 写入视频文件,关闭所有资源避免内存泄漏
        final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")
        video1.close()
        video2.close()
        combined_clip.close()
        final_clip.close()
        
        return output_path

    # 在线程中执行同步处理逻辑,不阻塞事件循环
    return await asyncio.to_thread(process_single_video)

if __name__ == "__main__":
    # 确保输出目录存在
    os.makedirs(chemin_semi_final, exist_ok=True)
    asyncio.run(upload())

关键优化点说明

  • 真正的并行处理:用asyncio.to_thread把MoviePy的同步操作放到线程池,让asyncio事件循环可以同时调度多个视频处理任务,避免串行阻塞。
  • 资源复用与释放:提前加载随机视频避免重复IO;手动调用close()释放所有剪辑资源,防止内存溢出。
  • 并发控制:通过Semaphore限制同时处理的视频数量,防止系统CPU/内存被占满。
  • 跨平台路径处理:用os.path模块替代硬编码的路径分隔符,兼容Windows和Linux系统。

内容的提问来源于stack exchange,提问作者DI PAULI Théo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:43:13