使用 MoviePy 或 FFmpeg 连接 Python 列表中的电影

Concatenate Movies from Python List using MoviePy or FFmpeg

我有大约 10,000 个短视频,我正尝试从中制作几个较长的视频。

我使用 MoviePy 创建了这些视频,但在尝试将它们重新连接在一起时总是出现内存错误。

在我的代码中,我有一个外部循环遍历字母表中的每个字母并获取以该字母开头的文件。

从返回的视频剪辑中我得到了长度并去掉了视频的最后 3.5 秒 (outro_clip_duration),然后将其添加到 Python 列表中 clips .

我被卡住的地方是我想获取这个 trimmed 视频列表并从中制作一个很长的视频。

我有所有的文件,我只需要 trim 它们,连接它们,然后将它们作为一个导出。

我尝试了很多次不同的 MoviePy 尝试并不断收到 MemoryErrors,所以我放弃并尝试了一个 ffmpeg 解决方案 但它也没有解决。

我的代码主要部分的最新版本在这里:

clips = []
outro_clip = mpy.VideoFileClip('Logo_Intro_w_Stinger_Large.mp4')
outro_clip_duration = outro_clip.duration
for def_image in vid_list_long:
    video_item = mpy.VideoFileClip('F:/sm_My_Video/sm_%s.mp4' % def_image)
    video_item_duration = video_item.duration
    clips.append(ffmpeg_extract_subclip(video_item,0,(video_item_duration - outro_clip_duration), targetname = def_image))

# #Append the outro_clip to the end 
clips.append(mpy.VideoFileClip('Logo_Intro_w_Stinger_Large.mp4',target_resolution = (h,w),audio=True))
slided_clips = [CompositeVideoClip([clip.fx( transfx.crossfadein, transition_seconds)]) for clip in clips]
#added 'method = compose' NEED TO TEST - supposedly removes the weird glitches.
c = concatenate_videoclips(slided_clips, method = 'compose')
c.write_videofile('F:/Extended_Play/%s_Extended_Play_vid.mp4' % letter,fps=23.98)

我的电脑是 Windows 10,我有 32 GB 内存 运行 Anaconda 和 Python 3.

如果是内存问题,也许您可​​以尝试为字母表中的每个字母制作一个串联视频,然后在单独的脚本中尝试串联这些视频?我知道许多视频格式在顶部包含 headers,可能会占用很多 space,因此,如果您分步组合它们,您可以将更少的 headers 加载到内存中.也许(纯粹是推测,因为我真的不知道)您尝试制作的视频的文件格式存在限制,并且您超出了该限制,所以您想要的东西根本无法以该特定格式实现?如果这些建议不起作用,也许您可​​以尝试一次将视频连接一个字母(在您已经通过字母连接之后)并查看它在哪里中断?作为最后的手段,您总是可以降低分辨率,或者 post 将 YouTube(或您正在做的任何事情)作为 2 或 3 个视频而不是 1 个。与 10,000 个视频相比,这仍然是一个巨大的改进!

您应该在使用完剪辑后尝试关闭它们,方法是在 for 循环的末尾添加 close_clip(video_item),例如

for def_image in vid_list_long:
    video_item = mpy.VideoFileClip('F:/sm_My_Video/sm_%s.mp4' % def_image)
    video_item_duration = video_item.duration
    clips.append(ffmpeg_extract_subclip(video_item,0,(video_item_duration - outro_clip_duration), targetname = def_image))
    close_clip(video_item)

close_clip() 看起来像

def close_clip(clip):
  try:
    clip.reader.close()
    if clip.audio != None:
      clip.audio.reader.close_proc()
      del clip.audio
    del clip
  except Exception as e:
    print("Error in close_clip() ", e)
def concatenate():
    stringa = "ffmpeg -i \"concat:"
    elenco_video = glob.glob("*.mp4")
    elenco_file_temp = []
    for f in elenco_video:
        file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
        os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
        elenco_file_temp.append(file)
    print(elenco_file_temp)
    for f in elenco_file_temp:
        stringa += f
        if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
            stringa += "|"
        else:
            stringa += "\" -c copy  -bsf:a aac_adtstoasc output.mp4"
    print(stringa)
    os.system(stringa)

# call the method
concatenate()