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

基于字幕时间戳删除视频间隙的FFmpeg实现可行性问询

如何用FFmpeg保留字幕对应视频片段并删除间隙?

当然可行!用FFmpeg完全能实现只保留字幕覆盖的视频片段、删除间隙的需求,下面给你两种实用的方法,结合你提供的前20组时间戳来举例说明:

方法1:先切割片段再合并(适合新手,步骤清晰)

这个方法分两步:先把每个字幕对应的时间段单独切割成小视频,再把这些小视频无缝合并。

步骤1:批量切割片段

FFmpeg识别的时间格式是用点(.)分隔毫秒,所以先把你提取的时间戳里的逗号(,)换成点。比如第一组00:00:45,366 --> 00:00:47,499要改成00:00:45.366和00:00:47.499。

然后对每个时间戳执行切割命令:

# 第1个片段
ffmpeg -i input.mp4 -ss 00:00:45.366 -to 00:00:47.499 -c copy part_01.mp4
# 第2个片段
ffmpeg -i input.mp4 -ss 00:00:47.500 -to 00:00:51.165 -c copy part_02.mp4
# ... 以此类推,直到第20个片段

-c copy是直接复制音视频流,速度极快,但如果视频关键帧位置和片段起始点不匹配,可能会出现画面跳帧,这时候去掉-c copy,改用重新编码:

ffmpeg -i input.mp4 -ss 00:00:45.366 -to 00:00:47.499 -c:v libx264 -c:a aac -crf 23 part_01.mp4

步骤2:合并所有片段

创建一个文本文件parts_list.txt,内容格式如下:

file 'part_01.mp4'
file 'part_02.mp4'
file 'part_03.mp4'
...
file 'part_20.mp4'

然后执行合并命令:

ffmpeg -f concat -safe 0 -i parts_list.txt -c copy final_output.mp4

-safe 0是允许引用当前目录下的文件,避免路径报错。

方法2:用filter_complex一次性处理(高效,适合大量片段)

如果你的时间戳很多(比如几十上百组),手动切割太麻烦,可以用FFmpeg的filter_complex滤镜,一次性完成裁剪和合并,不需要生成中间文件。

命令模板(结合你的20组时间戳)

把所有字幕片段的trim滤镜串联起来,再用concat合并:

ffmpeg -i input.mp4 -filter_complex "
[0:v][0:a]trim=start=00:00:45.366:end=00:00:47.499[v1][a1];
[0:v][0:a]trim=start=00:00:47.500:end=00:00:51.165[v2][a2];
[0:v][0:a]trim=start=00:00:51.166:end=00:00:56.132[v3][a3];
[0:v][0:a]trim=start=00:01:47.000:end=00:01:49.265[v4][a4];
[0:v][0:a]trim=start=00:01:49.266:end=00:01:51.365[v5][a5];
[0:v][0:a]trim=start=00:02:06.366:end=00:02:11.665[v6][a6];
[0:v][0:a]trim=start=00:02:11.666:end=00:02:13.799[v7][a7];
[0:v][0:a]trim=start=00:02:16.766:end=00:02:20.999[v8][a8];
[0:v][0:a]trim=start=00:02:21.000:end=00:02:24.732[v9][a9];
[0:v][0:a]trim=start=00:02:24.733:end=00:02:26.999[v10][a10];
[0:v][0:a]trim=start=00:02:27.000:end=00:02:30.932[v11][a11];
[0:v][0:a]trim=start=00:02:30.933:end=00:02:33.465[v12][a12];
[0:v][0:a]trim=start=00:02:33.466:end=00:02:36.465[v13][a13];
[0:v][0:a]trim=start=00:02:36.466:end=00:02:37.732[v14][a14];
[0:v][0:a]trim=start=00:02:37.733:end=00:02:40.299[v15][a15];
[0:v][0:a]trim=start=00:02:40.300:end=00:02:42.265[v16][a16];
[0:v][0:a]trim=start=00:02:45.300:end=00:02:48.265[v17][a17];
[0:v][0:a]trim=start=00:02:48.266:end=00:02:50.532[v18][a18];
[0:v][0:a]trim=start=00:02:50.533:end=00:02:55.365[v19][a19];
[0:v][0:a]trim=start=00:02:55.366:end=00:03:02.132[v20][a20];
[v1][a1][v2][a2][v3][a3][v4][a4][v5][a5][v6][a6][v7][a7][v8][a8][v9][a9][v10][a10][v11][a11][v12][a12][v13][a13][v14][a14][v15][a15][v16][a16][v17][a17][v18][a18][v19][a19][v20][a20]concat=n=20:v=1:a=1[outv][outa]
" -map "[outv]" -map "[outa]" final_output.mp4

解释一下:

  • trim滤镜用于裁剪每个时间段的音视频流,[0:v]是原视频的视频流,[0:a]是音频流;
  • concat滤镜把所有裁剪后的音视频流按顺序合并,n=20表示有20个片段,v=1:a=1表示输出1路视频和1路音频;
  • 最后用-map指定输出合并后的音视频流。

小技巧:自动生成命令

如果时间戳数量很多,手动写上面的命令太费劲,可以用Python脚本自动生成filter_complex的内容。比如读取你的时间戳文本文件,替换逗号为点,然后循环生成每个trim行和最后的concat行。

举个简单的Python脚本示例:

# 读取时间戳文件,假设文件名为timestamps.txt
with open('timestamps.txt', 'r') as f:
    lines = f.readlines()

filter_parts = []
concat_inputs = []

for idx, line in enumerate(lines, 1):
    # 提取时间范围,比如"1.00:00:45,366 --> 00:00:47,499"
    time_range = line.split('.')[1].strip()
    start, end = time_range.split(' --> ')
    # 替换逗号为点
    start = start.replace(',', '.')
    end = end.replace(',', '.')
    # 生成trim滤镜行
    filter_line = f"[0:v][0:a]trim=start={start}:end={end}[v{idx}][a{idx}];"
    filter_parts.append(filter_line)
    # 收集concat输入
    concat_inputs.append(f"[v{idx}][a{idx}]")

# 生成concat行
concat_line = ''.join(concat_inputs) + f"concat=n={len(lines)}:v=1:a=1[outv][outa]"
filter_parts.append(concat_line)

# 组合完整的filter_complex内容
filter_complex_content = '\n'.join(filter_parts)
print(filter_complex_content)

运行这个脚本,就能直接得到filter_complex里的内容,复制到FFmpeg命令里就行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:43:20