将FFmpeg转码DASH的视频编码从libx264改为libx265后仅有声无视频且报错
看起来你碰到的问题核心是libx265的关键帧行为和DASH分段要求不匹配,再加上你禁用了timeline模板,直接触发了分段时长差异过大的报错,导致播放器无法解析视频流。咱们一步步来解决:
先分析报错原因
你看到的错误:
Segment durations differ too much, enable use_timeline and use_template, or keep a stricter keyframe interval
意思很明确:要么启用timeline模板,要么严格控制关键帧间隔,让每个分段的时长保持一致。而你之前用-use_timeline 0关闭了时间线,同时关键帧间隔-g 250和10秒分段(30fps下应该是300帧)不对齐,再加上libx265的关键帧生成逻辑和x264有差异,就出现了视频流无法被正常识别的情况。
具体修改方案
我给你调整了命令参数,主要改了这几个关键点:
严格对齐关键帧与分段时长
因为你设置了-seg_duration 10(每个分段10秒),同时帧率是30fps,所以关键帧间隔-g应该设为300(10*30),并且让-keyint_min和-g保持一致,避免提前插入关键帧破坏分段对齐。启用timeline模板
按照报错提示,把-use_timeline 0改成-use_timeline 1,让FFmpeg生成时间线来统一分段时长,彻底解决时长差异问题。优化libx265的参数兼容性
保留-sc_threshold 0(你之前已经加了,这个很重要,避免场景变化时强制插入额外关键帧),同时确保libx265的profile参数正确(mainprofile是支持的)。
修改后的完整命令
ffmpeg -i /v.webm -preset slow -map_metadata -1 -profile:v main -c:v libx265 -pix_fmt yuv420p \ -keyint_min 300 -g 300 -sc_threshold 0 \ -map 0:a -c:a aac -b:a 128k -ac 2 -ar 48000 \ -map v:0 -filter:v:0 "scale=-2:144,fps=30" -minrate:v:0 90k -maxrate:v:0 150k -bufsize:v:0 60k \ -init_seg_name "init-$RepresentationID$.$ext$" \ -media_seg_name "chunk-$RepresentationID$-$Number%05d$.$ext$" \ -dash_segment_type mp4 \ -use_template 1 -use_timeline 1 -seg_duration 10 \ -adaptation_sets "id=0,streams=v id=1,streams=a" \ -f dash /dash.mpd
额外优化建议
如果你觉得固定码率模式下还是容易出现分段问题,可以试试CRF画质控制模式(更适合libx265),去掉-minrate、-maxrate、-bufsize,加上-x265-params crf=28(CRF值越小画质越好,28是x265的默认推荐值),这样画质更稳定,也更容易对齐分段。
备注:内容来源于stack exchange,提问作者Dmitrii

