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

Python MoviePy脚本字幕生成失败:API请求错误与文件查找异常

用MoviePy为视频添加字幕遇到的问题及解决方案

问题背景

使用Python的MoviePy库编写脚本为视频添加字幕,执行步骤如下:

  1. 加载视频文件
  2. 提取视频音频
  3. 通过Google Speech Recognition API转写音频
  4. 将转写内容作为字幕叠加到视频上
  5. 输出带字幕的新视频

但遇到两个具体错误:

  • 识别请求失败:调用Google Speech Recognition API时返回"Bad Request"错误
  • MoviePy错误:添加字幕时出现"creation of None failed"错误,伴随[WinError 2]系统找不到指定文件的提示

相关代码

def addCaptions(self):
    video = VideoFileClip(OUTPUT_FOLDER + OUTPUT_FILE_NAME + ".mp4")
    audio = video.audio
    temp_audio_path = OUTPUT_FOLDER + "temp_audio/temp_audio.wav"
    audio.write_audiofile(temp_audio_path, fps=audio.fps, codec='pcm_s16le')
    video.close()
    r = sr.Recognizer()
    transcription = ""
    with sr.AudioFile(temp_audio_path) as source:
        audio_data = r.record(source)
    try:
        transcription = r.recognize_google(audio_data)
    except sr.UnknownValueError:
        print("Unable to transcribe audio")
    except sr.RequestError as e:
        print("Recognition request failed:", e.reason)

    os.remove(temp_audio_path)

    font = "Arial"  
    fontsize = 24  
    txt_clip = TextClip(transcription, fontsize=fontsize, font=font, color='white')
    caption_video = CompositeVideoClip([video, txt_clip.set_pos(('center', 0.9))]) 
    caption_video.write_videofile(OUTPUT_FOLDER + OUTPUT_FILE_NAME + "_with_captions.mp4")
    video.close()

问题解决

1. Google Speech Recognition "Bad Request" 错误解决

  • 音频时长限制:Google免费语音识别API单段音频时长不能超过1分钟,若视频音频过长,需将音频分割为多个1分钟以内的片段分别转写,再合并结果。
  • 音频预处理:在录制音频数据前添加降噪处理,提升识别成功率:
    with sr.AudioFile(temp_audio_path) as source:
        r.adjust_for_ambient_noise(source)  # 添加降噪
        audio_data = r.record(source)
    
  • 网络与权限检查:确保网络可正常访问Google服务,若使用付费API需确认密钥配置正确;免费版有请求频次限制,避免短时间内多次请求。
  • 路径与格式检查:确认temp_audio_path对应的文件夹已创建(可提前用os.makedirs(os.path.dirname(temp_audio_path), exist_ok=True)创建),避免音频写入失败导致空文件被提交识别。

2. MoviePy "creation of None failed" 与 WinError 2 错误解决

  • 禁止复用已关闭的Video对象:代码中提前调用video.close()后,后续CompositeVideoClip复用video对象会导致资源已释放的错误。解决方式:要么不提前关闭video,要么在叠加字幕前重新加载视频:
    # 移除提前的video.close(),或在叠加字幕前重新加载:
    video = VideoFileClip(OUTPUT_FOLDER + OUTPUT_FILE_NAME + ".mp4")
    
  • 字体依赖修复:Windows系统中Arial字体可能无法被MoviePy正确识别,可尝试切换为系统内置通用字体(如黑体),或指定字体完整路径;同时确保安装了MoviePy依赖的ImageMagick,或指定用ffmpeg生成字幕:
    txt_clip = TextClip(transcription, fontsize=fontsize, font='simhei', color='white', method='ffmpeg')
    
  • 路径存在性检查:确保OUTPUT_FOLDER和临时音频文件夹存在,避免文件写入失败。添加路径创建代码:
    import os
    temp_audio_dir = os.path.join(OUTPUT_FOLDER, "temp_audio")
    os.makedirs(temp_audio_dir, exist_ok=True)
    temp_audio_path = os.path.join(temp_audio_dir, "temp_audio.wav")
    

修复后的示例代码

import os
import speech_recognition as sr
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip

def addCaptions(self):
    # 确保输出目录和临时音频目录存在
    os.makedirs(OUTPUT_FOLDER, exist_ok=True)
    temp_audio_dir = os.path.join(OUTPUT_FOLDER, "temp_audio")
    os.makedirs(temp_audio_dir, exist_ok=True)
    
    video_path = os.path.join(OUTPUT_FOLDER, f"{OUTPUT_FILE_NAME}.mp4")
    video = VideoFileClip(video_path)
    audio = video.audio
    temp_audio_path = os.path.join(temp_audio_dir, "temp_audio.wav")
    
    # 写入音频文件
    audio.write_audiofile(temp_audio_path, fps=audio.fps, codec='pcm_s16le')
    
    # 语音识别
    r = sr.Recognizer()
    transcription = ""
    with sr.AudioFile(temp_audio_path) as source:
        r.adjust_for_ambient_noise(source)
        audio_data = r.record(source)
    try:
        transcription = r.recognize_google(audio_data)
        print(f"转写内容:{transcription}")
    except sr.UnknownValueError:
        print("无法识别音频内容")
    except sr.RequestError as e:
        print(f"识别请求失败:{e.reason}")

    os.remove(temp_audio_path)
    
    # 创建字幕片段并设置时长
    txt_clip = TextClip(transcription, fontsize=24, font='simhei', color='white', method='ffmpeg')
    txt_clip = txt_clip.set_pos(('center', 0.9)).set_duration(video.duration)
    
    # 合成视频
    caption_video = CompositeVideoClip([video, txt_clip])
    output_path = os.path.join(OUTPUT_FOLDER, f"{OUTPUT_FILE_NAME}_with_captions.mp4")
    caption_video.write_videofile(output_path)
    
    # 释放资源
    video.close()
    caption_video.close()

内容的提问来源于stack exchange,提问作者Atharva Vedpathak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:45:10