如何用FFmpeg设置DASH流片段时长?关键帧相关问题咨询
FFmpeg DASH分片时长问题解答
a) seg_duration与关键帧间隔的关系,及FFmpeg不自动添加关键帧的原因
DASH分片的起始必须是关键帧——因为播放器只能从关键帧开始解码播放,非关键帧依赖前面的关键帧才能解析。
seg_duration只是你期望的分片时长,但FFmpeg默认不会主动插入关键帧来满足这个时长,原因有两点:
- 关键帧密度直接影响编码效率和视频体积:过多关键帧会导致文件变大,FFmpeg不会随意修改输入视频的原有关键帧布局(除非你明确指定参数)。
- 如果输入视频的关键帧间隔(GOP长度)远大于
seg_duration,FFmpeg只能等到下一个自然存在的关键帧出现时才切割分片,最终分片时长就等于两个关键帧的间隔,而非你设置的seg_duration。比如你输入视频的GOP是8秒,那分片就会是8秒左右。
b) 获取符合预期的分片长度的方法
不需要设置过小的-g(比如5),可以用以下两种更合理的方案:
方案1:强制按时间间隔生成关键帧(推荐)
使用-force_key_frames "expr:gte(t,n_forced*1)"参数,让FFmpeg每1秒强制插入一个关键帧,刚好匹配seg_duration的设置:
ffmpeg -i input.mp4 -preset veryfast \ -c:v libx264 -pix_fmt yuv420p -map 0:v:0 \ -s:0 1280x720 -b:v:0 2M -maxrate:0 2.5M -bufsize:0 4M \ -force_key_frames "expr:gte(t,n_forced*1)" \ -use_template 1 -use_timeline 1 -seg_duration 1 -f dash foo/stream.mpd
这个表达式的作用是:在每个整数秒(t=1,2,3...)的位置强制生成关键帧,FFmpeg就能精准在每1秒处切割分片。
方案2:匹配GOP长度与分片时长
如果知道输入视频的帧率,可以设置-g等于帧率 × 分片时长。比如视频是25fps,1秒分片就设置-g 25;30fps则设置-g 30,让GOP长度刚好等于1秒:
ffmpeg -i input.mp4 -preset veryfast \ -c:v libx264 -pix_fmt yuv420p -map 0:v:0 \ -s:0 1280x720 -b:v:0 2M -maxrate:0 2.5M -bufsize:0 4M \ -g 25 \ # 对应25fps的视频,1秒25帧 -use_template 1 -use_timeline 1 -seg_duration 1 -f dash foo/stream.mpd
不确定帧率的话,先执行ffmpeg -i input.mp4,查看输出中的fps参数即可。
内容的提问来源于stack exchange,提问作者ipartola
相关产品推荐
相关产品推荐

