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

基于帧数分割多段视频为短视频的技术方案咨询

基于帧号切割视频的实现方案

需求背景

原本通过秒数切割视频(如0-10秒、10-20秒),但因秒数计数存在误差,需改为按帧号切割(如0-250帧、250-500帧)。原基于秒数切割的代码如下:

required_video_file = "H8.avi"

with open("Z:/temp/Letícia/Videos/teste/times.txt") as f:
    times = f.readlines()

times = [x.strip() for x in times] 

for time in times:
    starttime = int(time.split('-')[0])
    endtime = int(time.split("-")[1])
    ffmpeg_extract_subclip(required_video_file, starttime, endtime, targetname=str(times.index(time)+1)+".avi")

实现思路

核心是利用FFmpeg的帧级控制能力,以下两种方案均可行:

方案1:帧号转精确时间(适配原有代码逻辑)

ffmpeg_extract_subclip基于时间参数切割,我们可以先获取视频帧率(FPS),将帧号转换为精确的时间值(时间 = 帧号 / FPS),再传入原函数完成切割,无需大幅改动原有代码结构。

修改后的代码示例:

from moviepy.editor import VideoFileClip, ffmpeg_extract_subclip

required_video_file = "H8.avi"

# 获取视频帧率
with VideoFileClip(required_video_file) as clip:
    fps = clip.fps

# 读取帧号区间文件(需将原times.txt改为帧号格式,如每行"0-250")
with open("Z:/temp/Letícia/Videos/teste/frames.txt") as f:
    frame_ranges = f.readlines()

frame_ranges = [x.strip() for x in frame_ranges if x.strip()]

for idx, frame_range in enumerate(frame_ranges):
    start_frame, end_frame = map(int, frame_range.split('-'))
    # 帧号转精确时间
    start_time = start_frame / fps
    end_time = end_frame / fps
    # 执行切割
    target_name = f"{idx+1}.avi"
    ffmpeg_extract_subclip(required_video_file, start_time, end_time, targetname=target_name)

方案2:直接调用FFmpeg命令按帧切割(更精准)

跳过时间转换环节,直接使用FFmpeg原生的-start_frame(起始帧)和-vframes(截取帧数)参数实现帧级切割,彻底避免时间转换带来的潜在误差。

修改后的代码示例:

import subprocess

required_video_file = "H8.avi"

# 读取帧号区间文件
with open("Z:/temp/Letícia/Videos/teste/frames.txt") as f:
    frame_ranges = f.readlines()

frame_ranges = [x.strip() for x in frame_ranges if x.strip()]

for idx, frame_range in enumerate(frame_ranges):
    start_frame, end_frame = map(int, frame_range.split('-'))
    # 计算需要截取的帧数:结束帧 - 起始帧
    frame_count = end_frame - start_frame
    target_name = f"{idx+1}.avi"
    # 构造FFmpeg命令
    cmd = [
        "ffmpeg",
        "-i", required_video_file,
        "-start_frame", str(start_frame),
        "-vframes", str(frame_count),
        "-c:v", "copy",  # 直接复制视频流,无重新编码,速度极快
        "-c:a", "copy",  # 直接复制音频流(无需音频可删除此行)
        target_name
    ]
    # 执行命令
    subprocess.run(cmd, check=True)

注意事项

  • 确保frames.txt每行格式为起始帧-结束帧(如0-250),帧号为非负整数;
  • 方案2中-c:v copy和-c:a copy参数仅适用于支持帧级截断的编码格式,若切割后视频无法播放,可删除这两个参数让FFmpeg重新编码;
  • 多数视频帧号从0开始计数,需确认原视频的帧计数规则,避免切割偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:20:23