FFmpeg concat输入文件duration参数失效及DTS异常问题咨询
问题分析与解决方案
让我来帮你拆解下遇到的两个问题,以及对应的解决办法:
为什么duration 3参数不生效?
你的核心问题出在三个地方:
- FFmpeg版本太老旧:你使用的3.4.2是2018年的版本,concat demuxer(即
-f concat模式)对duration参数的支持存在bug,尤其是在-c copy(直接复制流)模式下,无法正确截断视频。 - 帧率不匹配:你生成黑屏视频时用了
r=1(1fps),而目标视频的帧率大概率远高于这个值。帧率不一致会导致concat demuxer无法正确解析时间戳,进而忽略duration参数,直接播放完整的10秒黑屏。 - copy模式的限制:
-c copy是直接复制视频数据包,若要截断到3秒,需要3秒位置正好是关键帧。但你生成的黑屏视频可能只有开头一个关键帧,copy模式下无法在非关键帧位置截断,只能播放到视频结束。
为什么会出现"Non-monotonous DTS"警告?
这个警告是因为黑屏视频和目标视频的时间戳(DTS/PTS)不连续。黑屏视频每帧持续1秒,目标视频每帧持续时间(比如1/25秒)短很多,拼接后时间戳出现跳变,FFmpeg就会抛出这个警告。
解决方案(按推荐程度排序)
方案1:直接生成匹配帧率的3秒黑屏(最简单高效)
先确认目标视频的帧率,用ffprobe查看:
ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 video_example.mkv
假设输出是25/1(25fps),那么生成3秒黑屏的命令:
ffmpeg -f lavfi -i color=black:s=320x240:r=25 -t 3 -an blank_3s.mkv
这里r=25和目标视频帧率保持一致,避免时间戳冲突;-t 3直接生成3秒时长,无需后续截断。
然后创建input.txt:
file 'blank_3s.mkv' file 'video_example.mkv'
执行拼接:
ffmpeg -f concat -i input.txt -c copy output.mkv
这个方案既解决了duration不生效的问题,也不会出现DTS警告。
方案2:截取已有10秒黑屏的前3秒再拼接
如果不想重新生成黑屏,先截取前3秒:
ffmpeg -i blank.mkv -t 3 -c copy blank_3s.mkv
如果截取后时长还是不对(因为关键帧问题),就重新编码截取:
ffmpeg -i blank.mkv -t 3 -c:v libvpx -an blank_3s.mkv
之后再用方案1的concat命令拼接即可。
方案3:使用concat滤镜(适合需要重新编码的场景)
如果必须用duration参数或者需要统一视频参数,可以用concat滤镜(而非demuxer),它会重新编码视频,确保截断和时间戳连续:
# 无音轨场景 ffmpeg -i blank.mkv -i video_example.mkv -filter_complex "[0:v]trim=duration=3[v0];[v0][1:v]concat=n=2:v=1:a=0[v]" -map "[v]" -c:v libvpx output.mkv # 有音轨场景(需添加音轨处理) ffmpeg -i blank.mkv -i video_example.mkv -filter_complex "[0:v]trim=duration=3[v0];[v0][1:v]concat=n=2:v=1:a=0[v];[1:a]anullsrc=channel_layout=stereo:sample_rate=44100[a0];[a0][1:a]concat=n=2:v=0:a=1[a]" -map "[v]" -map "[a]" -c:v libvpx -c:a libvorbis output.mkv
这个方案速度会慢一些,但能彻底解决所有问题。
额外建议
你的FFmpeg版本3.4.2真的太老了,很多bug在新版本中都已修复。建议升级到最新的稳定版(比如6.x或5.x),后续使用concat等功能会顺畅很多。
内容的提问来源于stack exchange,提问作者Voicu




