视频切割脚本(Python版)

1.脚本用途

将一个长视频按固定时长进行切分

2.使用步骤

保存脚本

将下方的 Python 代码保存为一个 .py 文件,例如 split_video.py

放置视频

将你想要切割的 .mp4 视频文件,和这个 split_video.py 脚本放在同一个文件夹下

请确保该文件夹内只有一个 .mp4 文件,脚本会自动处理找到第一个

运行脚本

在该文件夹路径下打开终端或命令行,输入 python split_video.py 并回车,脚本便会自动开始工作

3.脚本逻辑说明

配置区域

脚本开头定义了三个关键参数,可根据需求自行修改:

①SEGMENT_MINUTES = 3:定义每个标准片段的时长,这里是3分钟

②MERGE_THRESHOLD = 120:定义合并阈值,单位是秒,如果最后一段视频小于120s,就会将最后一段合并到前一段中

③output_dir:定义了输出文件夹的名称,默认为 output_segments

计算分段点

①初步切分:首先,脚本会计算视频总时长,然后按照 SEGMENT_MINUTES 生成一个初步的切割时间点列表。例如,一个10分钟的视频会生成 0 , 180 , 360 , 540 秒这几个切割点

②智能判断:计算最后一段的实际时长

③合并:如果最后一段的时长<MERGE_THRESHOLD,脚本就会从切割点列表中移除最后一个点

执行切割循环

①遍历最终确定的切割点列表,使用 moviepy 的 subclip 方法逐一截取视频片段

②每个片段都会被保存为 原文件名_part_01.mp4、原文件名_part_02.mp4 的格式

③脚本还内置了简单的重试机制和内存清理(gc.collect()),以增强处理的稳定性

4.前置环境准备

①安装 Python 并完成环境配置

②安装依赖库:该脚本依赖强大的 moviepy 库来处理视频

请在终端或命令行中运行以下命令进行安装👇

bash 复制代码
pip install moviepy

注意:根据脚本内的错误提示,如果遇到版本兼容性问题,可以尝试安装特定版本👇、

bash 复制代码
pip install moviepy==1.0.3

5.效果展示

视频切割脚本效果演示

6.源码展示

python 复制代码
import os
import gc
import time
from moviepy.editor import VideoFileClip

def split_video_smart_merge():
    # --- 配置区域 ---
    SEGMENT_MINUTES = 3          # 正常每段时长:3分钟
    MERGE_THRESHOLD = 120        # 【关键】合并阈值:120秒(2分钟)。若尾段小于此值则合并
    
    current_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(current_dir, "output_segments")
    
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    video_files = [f for f in os.listdir(current_dir) if f.endswith('.mp4')]
    if not video_files:
        print("错误:未找到 .mp4 视频文件!")
        return
        
    video_path = os.path.join(current_dir, video_files[0])
    print(f"正在处理: {video_files[0]}")

    # 获取总时长
    try:
        temp_clip = VideoFileClip(video_path)
        total_duration = temp_clip.duration
        temp_clip.close() 
    except Exception as e:
        print(f"读取视频失败: {e}")
        return

    segment_duration = SEGMENT_MINUTES * 60
    
    # --- 核心逻辑:计算分段点 ---
    # 1. 先按标准3分钟切分
    cuts = list(range(0, int(total_duration), segment_duration))
    
    # 2. 检查最后一段是否太短
    if len(cuts) > 1: 
        last_segment_duration = total_duration - cuts[-1]
        
        if last_segment_duration < MERGE_THRESHOLD:
            print(f"检测到最后一段时长为 {last_segment_duration:.1f}秒 (小于{MERGE_THRESHOLD}秒)")
            print(f"策略:将最后一段合并到第 {len(cuts)-1} 段中。")
            cuts.pop()
        else:
            print(f"最后一段时长 {last_segment_duration:.1f}秒,保持独立。")

    print(f"最终计划切割为 {len(cuts)} 个片段。开始处理...\n")

    # --- 执行切割循环 ---
    for i in range(len(cuts)):
        start_time = cuts[i]
        
        # 如果是最后一段,结束时间就是视频总时长;否则是下一个切割点
        if i == len(cuts) - 1:
            end_time = total_duration
        else:
            end_time = cuts[i+1]
            
        part_num = i + 1
        output_filename = f"{os.path.splitext(video_files[0])[0]}_part_{part_num:02d}.mp4"
        output_path = os.path.join(output_dir, output_filename)
        
        print(f"--- 正在处理第 {part_num}/{len(cuts)} 段 ({start_time}s - {end_time}s) ---")
        
        success = False
        retry_count = 0
        
        # 重试机制
        while not success and retry_count < 3:
            try:
                sub_clip = VideoFileClip(video_path).subclip(start_time, end_time)
                
                # 【修改点】
                # 1. 删除了 logger=None,默认会显示 MoviePy 的进度条
                # 2. 如果不想看太多杂色信息,可以加上 verbose=False (视版本而定)
                sub_clip.write_videofile(
                    output_path,
                    codec="libx264",
                    audio_codec="aac",
                    preset="ultrafast",
                    # logger='bar'  # 如果你想强制显示条形进度条,取消这行注释
                )
                
                sub_clip.close()
                success = True
                
            except Exception as e:
                retry_count += 1
                error_msg = str(e)
                # 简单的过滤,避免报错信息太长刷屏
                if "unexpected keyword" in error_msg:
                     print(f"  ⚠️ 版本不兼容错误,请尝试运行: pip install moviepy==1.0.3")
                     return # 直接退出,因为重试也没用
                
                print(f"  ⚠️ 处理失败 (尝试 {retry_count}/3): {error_msg[:80]}...")
                gc.collect()
                time.sleep(2) 

        if success:
            print(f"  ✅ 成功保存: {output_filename}\n")
        else:
            print(f"  ❌ 最终失败: {output_filename}\n")

        # 每一段处理完,强制休息并清理内存
        gc.collect()
        time.sleep(1) 

    print("\n所有任务已完成!请在 output_segments 文件夹查看结果。")

if __name__ == "__main__":
    split_video_smart_merge()
相关推荐
阿俊-全栈开发7 分钟前
LikeShop 单商户SaaS商城分销模块二开:佣金计算与结算逻辑实现
java·开发语言·微服务·likeshop·likeshop开源商城·likeshop多商户
可爱系程序猿1 小时前
键鼠都正常、只有手柄映射才提示 dinput8.dll?DirectInput 接口和游戏目录怎么对齐
程序人生·游戏·电脑
夏天拐跑了西瓜2 小时前
一文入门LangChain:从框架认知到构建你的第一个AI Agent
python·langchain·conda·agent
夜听莺儿鸣3 小时前
502-002_Linux驱动开发模块化编程
linux·驱动开发·模块化编程
魔猴疯猿3 小时前
从0到1用Python开发第一个智能体
人工智能·python·深度学习·神经网络·机器学习
ychqsq3 小时前
201.春风
经验分享·职场和发展
wuminyu3 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
m0_380743873 小时前
C++中的freopen的用法实例详解
开发语言·c++
xiaoqi01954 小时前
机器学习因子分析实战:从量化特征到可视化决策
人工智能·python·机器学习
科力锐品牌君4 小时前
应用级灾备 | 海量非结构化数据如何实现高效数据保护
linux·运维·网络·安全·系统安全·数据安全·灾备