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

Windows环境MoviePy报OSError: [WinError 6]错误的解决求助

MoviePy 拼接视频剪辑时触发 TypeError 及 WinError 6 问题修复

环境信息

  • 系统:Windows 11
  • Python版本:3.10.11
  • 依赖库:MoviePy

问题现象

调用concatenate_videoclips拼接视频剪辑时,先触发TypeError: unsupported operand type(s) for +: 'int' and 'NoneType',随后出现OSError: [WinError 6] 句柄无效。手动关闭视频/音频剪辑对象后问题仍存在,需非多线程方案修复。

参考实现代码

def clip(
        content: str, 
        video_file: str, 
        outfile: str, 
        image_file: str = '', 
        offset: int = 0, 
        duration: int = 0):
    """
    Generate the Complete Clip
    content: str - Full content text
    video_file: str - Background video
    outfile: str - Filename of output
    image_file: str - Banner to display
    offset: int - Offset starting point of background video (default: 0)
    duration: int - Limit the video (default: audio length)
    """
    audio_comp, text_comp = generate_audio_text(split_text(content))

    audio_comp_list = []
    for audio_file in track(audio_comp, description='Stitching Audio...'):
        audio_comp_list.append(AudioFileClip(audio_file))
    audio_comp_stitch = concatenate_audioclips(audio_comp_list)
    audio_comp_stitch.write_audiofile('temp_audio.mp3', fps=44100)

    audio_duration = audio_comp_stitch.duration
    if duration == 0:
        duration = audio_duration

    audio_comp_stitch.close()

    vid_clip = VideoFileClip(video_file).subclip(offset, offset + duration)
    vid_clip = vid_clip.resize((1980, 1280))
    vid_clip = vid_clip.crop(x_center=1980 / 2, y_center=1280 / 2, width=720, height=1280)

    if image_file != '':
        image_clip = ImageClip(image_file).set_duration(duration).set_position(("center", 'center')).resize(0.8) # Adjust if the Banner is too small
        vid_clip = CompositeVideoClip([vid_clip, image_clip])

    vid_clip = CompositeVideoClip([vid_clip, concatenate_videoclips(text_comp).set_position(('center', 860))])

    vid_clip = vid_clip.set_audio(AudioFileClip('temp_audio.mp3').subclip(0, duration))
    vid_clip.write_videofile(outfile, audio_codec='aac')
    vid_clip.close()

测试简化代码

clip1 = TextClip(
  txt="test",
  font="Komika",  # Change Font if not found
  fontsize=32,
  color="white",
  align="center",
  method="caption",
  size=(660, None),
  stroke_width=2,
  stroke_color="black",
)
clip2 = TextClip(
  txt="webos",
  font="Komika",  # Change Font if not found
  fontsize=32,
  color="white",
  align="center",
  method="caption",
  size=(660, None),
  stroke_width=2,
  stroke_color="black",
)
conc = concatenate_videoclips([clip1, clip2]).set_position(("center", 860))

错误输出

PS C:\Users\ernes\OneDrive\Desktop\Bots\autocap\autocap_with_mp3> python .\autocap_with_mp3.py text.txt
Traceback (most recent call last):
  File "C:\Users\ernes\OneDrive\Desktop\Bots\autocap\autocap_with_mp3\autocap_with_mp3.py", line 218, in <module>
    main()
  File "C:\Users\ernes\OneDrive\Desktop\Bots\autocap\autocap_with_mp3\autocap_with_mp3.py", line 207, in main
    generate_video(
  File "C:\Users\ernes\OneDrive\Desktop\Bots\autocap\autocap_with_mp3\autocap_with_mp3.py", line 165, in generate_video
    conc = concatenate_videoclips([clip1, clip2]).set_position(("center", 860))
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\moviepy\video\compositing\concatenate.py", line 71, in concatenate_videoclips
    tt = np.cumsum([0] + [c.duration for c in clips])
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\core\fromnumeric.py", line 2586, in cumsum
    return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out)
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\core\fromnumeric.py", line 56, in _wrapfunc
    return _wrapit(obj, method, *args, **kwds)
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\numpy\core\fromnumeric.py", line 45, in _wrapit
    result = getattr(asarray(obj), method)(*args, **kwds)
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
Exception ignored in: <function FFMPEG_AudioReader.__del__ at 0x000001E727215120>
Traceback (most recent call last):
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\moviepy\audio\io\readers.py", line 254, in __del__
    self.close_proc()
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\site-packages\moviepy\audio\io\readers.py", line 149, in close_proc
    self.proc.terminate()
  File "C:\Users\ernes\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1589, in terminate
    _winapi.TerminateProcess(self._handle, 1)
OSError: [WinError 6] The handle is invalid
PS C:\Users\ernes\OneDrive\Desktop\Bots\autocap\autocap_with_mp3> 

问题根源

concatenate_videoclips需要每个输入剪辑都有明确的duration属性来计算拼接时间线。你创建的TextClip未设置时长,导致c.duration为None,numpy计算累加和时触发int + NoneType的类型错误。后续的WinError 6是该错误引发的连锁问题——子进程句柄因异常退出无法正常终止。

修复方案

1. 给TextClip设置明确时长

所有参与拼接的TextClip必须通过.set_duration()方法指定时长,测试代码修改如下:

clip1 = TextClip(
  txt="test",
  font="Komika",
  fontsize=32,
  color="white",
  align="center",
  method="caption",
  size=(660, None),
  stroke_width=2,
  stroke_color="black",
).set_duration(2)  # 设置2秒时长
clip2 = TextClip(
  txt="webos",
  font="Komika",
  fontsize=32,
  color="white",
  align="center",
  method="caption",
  size=(660, None),
  stroke_width=2,
  stroke_color="black",
).set_duration(2)
conc = concatenate_videoclips([clip1, clip2]).set_position(("center", 860))

业务代码中,text_comp里的每个TextClip建议与对应音频片段的时长匹配,保证音画同步。

2. 优化资源管理(可选)

使用with语句管理音频剪辑对象,避免句柄泄漏:

with AudioFileClip('temp_audio.mp3') as audio_clip:
    vid_clip = vid_clip.set_audio(audio_clip.subclip(0, duration))

验证

修改后重新运行代码,concatenate_videoclips能正常计算拼接时间线,TypeError和WinError 6都会消失。

内容的提问来源于stack exchange,提问作者ernesto casco velazquez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:02:50