You need to enable JavaScript to run this app. Python实现MP4长视频切割为5分钟分片并逐片转写的方法
优惠活动
大模型
产品
解决方案
定价
更多

Python实现MP4长视频切割为5分钟分片并逐片转写的方法

基于现有技术栈的长MP4切割+逐片转写实现

这套方案完全复用你已经验证过的代码逻辑,不需要额外引入重型依赖,改完即可直接运行,核心改动分为三部分:

1. 补全基础依赖与目录配置

  • 首先修改顶部的导入语句:因为现在需要读取完整视频做切割,原来仅导入的AudioFileClip无法满足视频读取需求,需要补充导入VideoFileClip,将原来的from moviepy.editor import AudioFileClip 改为 from moviepy.editor import AudioFileClip, VideoFileClip
  • 在原有os.chdir的路径配置之后,新增两项基础配置:
    • 定义分片时长常量:SEGMENT_LENGTH = 5 * 60 # 单位为秒,后续调整分片时长直接修改这个值即可
    • 自动创建分片存储目录:os.makedirs("video_segments", exist_ok=True),该目录会专门存放切好的5分钟独立mp4文件,exist_ok=True参数可以避免目录已存在时报错,避免切好的文件和原视频、转写结果混放。

2. 嵌入视频切割逻辑模块

替换原来直接读取原视频全量提取音频的流程,先完成原视频的分片切割,代码可直接加在原文件读取的对应位置:

# 读取原长视频文件
with VideoFileClip(mp4_video_file_name) as full_video:
    # 获取视频总时长
    total_duration = full_video.duration
    # 计算总共需要切多少个5分钟的分片
    total_segments = math.ceil(total_duration / SEGMENT_LENGTH)

    # 逐段切割并导出
    for seg_idx in range(total_segments):
        # 计算当前分片的开始、结束时间
        start = seg_idx * SEGMENT_LENGTH
        end = min((seg_idx + 1) * SEGMENT_LENGTH, total_duration)
        # 截取对应时间范围的视频片段
        segment = full_video.subclip(start, end)
        # 生成分片文件路径,命名格式为 原文件名_segment序号.mp4
        segment_save_path = os.path.join("video_segments", f"{FILE}_segment{seg_idx}.mp4")
        # 导出分片mp4,加参数优化导出速度、减少冗余日志
        segment.write_videofile(
            segment_save_path,
            codec="libx264",
            audio_codec="aac",
            verbose=False,
            logger=None
        )

切割生成的mp4会完整保留原视频的全部音视频流,不会出现音画不同步的问题,不需要额外做对齐处理。

3. 调整转写流程,逐分片执行处理

你原来编写的“按1分钟切片调用谷歌接口识别”的核心逻辑可以完全复用,只需要调整成遍历切割好的分片、对每个分片单独提取音频执行识别即可,不需要改动已验证可用的识别调用部分:

  • 先把单文件转写的流程封装成通用函数,避免重复写代码:
def process_single_segment(mp4_segment_path, final_result_file, recognizer):
    # 从分片mp4中提取音轨
    audio = AudioFileClip(mp4_segment_path)
    # 生成临时wav文件,供speech_recognition读取
    temp_wav = os.path.splitext(mp4_segment_path)[0] + "_temp.wav"
    audio.write_audiofile(temp_wav, verbose=False, logger=None)

    # 读取临时wav的总时长
    with contextlib.closing(wave.open(temp_wav, 'r')) as f:
        frames = f.getnframes()
        rate = f.getframerate()
        wav_duration = frames / float(rate)
    
    # 沿用原有1分钟切片识别逻辑(适配谷歌识别的接口时长限制)
    total_min = math.ceil(wav_duration / 60)
    segment_text = ""
    for i in range(total_min):
        with sr.AudioFile(temp_wav) as source:
            audio_chunk = recognizer.record(source, offset=i*60, duration=60)
        chunk_text = recognizer.recognize_google(audio_chunk, language="en-US")
        segment_text += chunk_text + " "
    
    # 清理临时文件,避免占用磁盘空间
    os.remove(temp_wav)
    audio.close()

    # 把当前分片的转写结果追加写入总结果文件
    with open(final_result_file, "a", encoding="utf-8") as f:
        f.write(f"\n--- 分片 {os.path.basename(mp4_segment_path)} 内容 ---\n")
        f.write(segment_text)
  • 所有视频分片切割完成后,遍历分片目录里的所有mp4文件,逐个调用上面的函数处理:
# 初始化语音识别器
recognizer = sr.Recognizer()
# 定义最终总转写结果的保存路径
full_transcript_save = FILE + "_full_transcription.txt"

# 遍历分片目录下的所有mp4文件,按序号顺序处理
for seg_name in sorted(os.listdir("video_segments")):
    if seg_name.endswith(".mp4"):
        seg_full_path = os.path.join("video_segments", seg_name)
        print(f"开始转写分片: {seg_name}")
        process_single_segment(seg_full_path, full_transcript_save, recognizer)

print("所有分片切割、转写流程执行完成。")

实操注意点

  • 如果使用的moviepy版本较新,subclip方法需要改成subclipped,按照控制台提示的方法名调整即可
  • 原来的代码在循环中频繁打开、关闭结果文件,容易出现文件句柄占用的问题,现在统一在函数内做文件读写,稳定性更高
  • 如果遇到谷歌识别接口偶发报错,可以在调用recognize_google的位置加简单的异常捕获,识别失败时标记对应段落为识别失败,不会因为单段错误中断整个批处理流程
  • 切割过程不会修改原文件,所有生成的分片、临时wav都单独存放在对应目录,后续需要清理临时文件时操作成本很低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 12:06:06