使用moviepy实现循环与变速时出现访问时间超出剪辑总时长报错
问题原因
- 特效执行顺序错误:当前你先执行
loop循环,再执行speedx变速,会导致moviepy内部时长计算逻辑混乱。正确顺序应该是先变速,再做循环,变速会先改变原片段的实际时长,再基于调整后的时长做循环,时长计算才不会出错 - 最终合成片段的时长设置错误:你给
final_clip设置的时长是原视频vtuber_clip.duration,但你前面已经给masked_clip设置了13秒的时长,底层的音频轨道没有同步截断,导致渲染时音频尝试读取超过原视频时长的帧 - 蒙版处理后没有显式处理音频同步,原视频的音频轨道还是跟随原视频的时长参数,没有和变速、循环后的视频同步
修复后的代码
import os import moviepy.editor as mpe ASSETS_PATH = "替换为你自己的资源路径" video = ColorClip(color=(255, 255, 255), size=(1920, 1080))\ .set_duration(15)\ .set_fps(30)\ .set_audio(None) vtuber_clip = VideoFileClip(os.path.join(ASSETS_PATH, 'videos/test1.mp4')) # 调整特效执行顺序,同步处理音频避免时长不匹配 masked_clip = vtuber_clip.fx(mpe.vfx.mask_color, color=[0,214,11], thr=100, s=5)\ .fx(mpe.vfx.speedx, 4) \ .fx(mpe.vfx.loop, duration=13) \ # 直接传duration参数自动计算循环次数,不需要手动算n值 .set_pos(('right', 'bottom'))\ .set_duration(13) \ # 如果不需要原视频音频,直接把下面一行替换为.set_audio(None)即可 .set_audio(mpe.afx.audio_loop(vtuber_clip.audio.fx(mpe.afx.audio_speedx, 4), duration=13)) # 最终合成时长按需设置即可,不要用原视频的时长参数 final_clip = CompositeVideoClip([video, masked_clip])\ .set_duration(15) # 不要和输入源文件同名,避免覆盖原素材 final_clip.write_videofile('test1_output.mp4')
额外注意点
- 不要让输入输出文件同名,会导致源文件被覆盖,后续调试找不到原素材
- 如果不需要保留原视频的音频,直接给
masked_clip加.set_audio(None),可以直接规避音频时长不匹配的问题 - 如果需要固定循环后的时长,直接给
loop传duration=目标时长参数,moviepy会自动计算需要循环的次数,不用手动计算循环次数n,不容易出错
内容的提问来源于stack exchange,提问作者Miguelo
相关产品推荐
相关产品推荐

