繁体   English   中英

使用 Python MoviePY 连接视频太慢

[英]Concat videos too slow using Python MoviePY

我正在使用 MoviePY 加入 50 秒或更多 1、2、3 分钟的视频,但它给了我 20 小时,即使我有 64 GB 的内存、i7 和 GTX 670,但不是顶级但合理。 无论如何我可以加快这个过程吗?

padding = 10 # padding option
video_clips = [VideoFileClip(video_dir + video) for video in os.listdir(video_dir)]
video_fx_list = [video_clips[0]]

idx = video_clips[0].duration - padding
for video in video_clips[1:]:
video_fx_list.append(video.set_start(idx).crossfadein(padding))
idx += video.duration - padding

final_video = CompositeVideoClip(video_fx_list)
final_video.write_videofile(video_dir + 'myoutfile.mp4', fps=24)

我不需要这些剪辑的原始音频,删除它会加快速度吗? 虽然不知道如何删除音频/

在此处输入图片说明

您可以在write_videofile指定多个threads 通过使用机器的所有内核,它将显着加快导出速度。

final_video.write_videofile(video_dir + 'myoutfile.mp4', threads = 8, fps=24)

附加说明:

  • 您可以将所有视频resize为较低的分辨率(例如 720p)

  • 降低fps也有很大的不同,但 24 fps 已经得到了很好的优化

  • Moviepy 仅使用 CPU 来渲染视频。 考虑升级您的 CPU 或在云服务(例如 Amazon AWS、Google Cloud、MS Azure..)上运行您的程序以获得更好的性能

Python 在视频编辑方面效率不高。

如果您使用的是 MoviePY,请查看https://zulko.github.io/moviepy/ref/ffmpeg.html (也许使用更稳定的 github dev 版本)

您有一些直接调用 ffmpeg 的函数: https : //github.com/Zulko/moviepy/blob/master/moviepy/video/io/ffmpeg_tools.py因此对于像您这样的简单任务非常有效

我使用带有 ffmpeg parser -vcodec h264_nvenc cuda 加速。 它对我有用,在 Win10 和 ffmpeg 4.2.3 版本,NVIDA GPU 上。
(您应该为您的 GPU 找到指定的 ffmpeg-parser 。)
它会加速5~10倍。
我已经使用 cuda 实现了 [剪切剪辑、连续视频、交叉淡入淡出连续、添加背景音乐]...

'''
here is concat videos with cuda accelerate.
so you can subclip the video fragment and clip them, then concat with others.
'''


import os

def save_flist(files):
    f_data = 'file \'' + '\'\nfile \''.join(files) + '\''
    print(f_data)

    f_list = 'list.txt'
    with open(f_list, 'w', encoding='gbk') as f:
        f.write(f_data)
    return f_list

video_path = r'E:\py\mkv\\'
os.chdir(video_path)

output_path = 'output.mkv'

files = ['1.mkv', '2.mkv', '3.mkv', '4.mkv']
print(files)        # your video_names.

f_list = save_flist(files)

call = f'ffmpeg -f concat -safe 0 -i {f_list} -c copy {output_path} -y'         # only supporte the same video_format, copy and not recode.

call = f'ffmpeg -f concat -safe 0 -i {f_list} -vcodec h264_nvenc {output_path} -y'    # cuda accelerate.

print(call)

os.system(call)

os.remove(f_list)

要获得最佳加速,您需要使用moviepy ffmpeg-tools 下面是一个例子:

from moviepy.video.io.ffmpeg_tools import ffmpeg_merge_video_audio
# printing logs can be a bottleneck sometimes, so we put ffmpeg_ouput=False
# and logger = None
# you can change video codec(vcodec) or audio codec (acodec) as per your need
ffmpeg_merge_video_audio(video_path,
                         audio_path,
                         output_path,
                         vcodec='copy',
                         acodec='copy',
                         ffmpeg_output=False,
                         logger=None)

而且我建议它在standalone process运行(主进程/线程除外)。 您可以使用 python 中的multiprocessing模块轻松完成。

但即使你想坚持使用final_video.write_videofile() ,我会说,通过verbose=Falselogger=None来让你在 I/O 中获得一些加速。 并且还可以threads=as you want使用threads=as you want 像下面这样:

final_video.write_videofile(video_dir + 'myoutfile.mp4', 
                           fps=24, 
                           verbose=False,
                           logger=None,
                           threads=32)

我实际上不确定为什么这会如此之慢,因为无论如何,这个write_videofile()正在使用 ffmpeg。 例如:

# from the source of moviepy (ffmpeg_writer.py - line 80 onwards)
cmd = [
            get_setting("FFMPEG_BINARY"),
            '-y',
            '-loglevel', 'error' if logfile == sp.PIPE else 'info',
            '-f', 'rawvideo',
            '-vcodec', 'rawvideo',
            '-s', '%dx%d' % (size[0], size[1]),
            '-pix_fmt', 'rgba' if withmask else 'rgb24',
            '-r', '%.02f' % fps,
            '-an', '-i', '-'
        ]

.... more codes

if threads is not None:
    cmd.extend(["-threads", str(threads)])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM