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

如何用FFmpeg生成适配dash.js的多码率MPEG-DASH流及MPD文件

嘿,我来帮你梳理一下生成支持dash.js质量选择器的多码率DASH MPD文件需要的关键配置和参数——刚好我之前做过不少类似的项目,踩过的坑也能给你提个醒~

核心前提:先搞定多码率媒体分片

在生成MPD之前,你得先准备好几组同编码、同帧率、分片时长一致的媒体文件(视频+音频):

  • 视频:不同分辨率(如1080p、720p、480p)对应不同码率,编码格式统一(比如H.264/AVC或H.265/HEVC)
  • 音频:如果做音频码率切换,也要准备多组不同比特率的音频流;如果不需要,单一组通用音频即可
  • 所有分片的时长要保持一致(比如4秒),且关键帧对齐,这样dash.js才能无缝切换质量
MPD文件的关键配置参数

MPD是DASH的索引文件,核心是把不同码率的流组织成dash.js能识别的可切换集合,以下是必选和推荐配置:

1. 顶层<MPD>标签的必要属性

<MPD 
  xmlns="urn:mpeg:dash:schema:mpd:2011"
  type="static"  <!-- 点播用static,直播用dynamic -->
  profiles="urn:mpeg:dash:profile:isoff-on-demand:2011"  <!-- 点播标准profile,直播用urn:mpeg:dash:profile:isoff-live:2011 -->
  minBufferTime="PT4S"  <!-- 播放器最少缓存时长,建议和分片时长一致 -->
  mediaPresentationDuration="PT1H30M0S"  <!-- 总视频时长,点播必填 -->
>
  • type和profiles必须匹配,否则dash.js可能无法正确解析
  • minBufferTime设为分片时长,能减少卡顿

2. <AdaptationSet>:实现质量切换的核心容器

所有可切换的同类型流(比如不同码率的视频)必须放在同一个<AdaptationSet>里,这是dash.js显示质量选择器的关键!

<AdaptationSet 
  mimeType="video/mp4" 
  codecs="avc1.4D401E"  <!-- 视频编码格式,必须和所有视频流一致,比如H.264的avc1.xxx,H.265的hev1.xxx -->
  segmentAlignment="true"  <!-- 强制分片对齐,必填 -->
  startWithSAP="1"  <!-- 分片从关键帧开始,必填 -->
>
  <!-- 这里放不同码率的<Representation> -->
</AdaptationSet>

<!-- 音频单独的AdaptationSet(如果不需要音频切换,只放一个Representation即可) -->
<AdaptationSet 
  mimeType="audio/mp4" 
  codecs="mp4a.40.2"  <!-- AAC音频的标准codec值 -->
  segmentAlignment="true"
>
</AdaptationSet>
  • 不要把视频和音频放在同一个AdaptationSet里,否则dash.js无法区分音视频流
  • codecs的值必须准确,可以用ffprobe input.mp4 -show_streams查看媒体文件的codec信息

3. <Representation>:每个码率的具体配置

每个<Representation>对应一个码率的流,必须包含以下参数:

<Representation 
  id="1080p"  <!-- 唯一标识,建议用分辨率或码率命名,方便识别 -->
  bandwidth="2000000"  <!-- 比特率,单位bps!这是dash.js质量选择器显示的核心数值,必须准确 -->
  width="1920" 
  height="1080" 
  frameRate="30"  <!-- 帧率,所有视频Representation必须一致 -->
>
  <!-- 分片模板,指向实际的媒体分片文件 -->
  <SegmentTemplate 
    timescale="30000"  <!-- 时间刻度,和帧率匹配:30帧的话用30000,25帧用25000 -->
    duration="120000"  <!-- 分片时长(timescale * 秒数):30000*4=120000(4秒分片) -->
    initialization="video_1080p_init.mp4"  <!-- 初始化文件(moov box) -->
    media="video_1080p_$Number$.mp4"  <!-- 分片文件模板,$Number$是分片序号 -->
  />
</Representation>

<!-- 再添加其他分辨率/码率的Representation -->
<Representation 
  id="720p" 
  bandwidth="1000000" 
  width="1280" 
  height="720" 
  frameRate="30"
>
  <SegmentTemplate 
    timescale="30000"
    duration="120000"
    initialization="video_720p_init.mp4"
    media="video_720p_$Number$.mp4"
  />
</Representation>
  • bandwidth必须是实际的比特率(不是文件大小/时长的近似值),dash.js会根据这个值排序并显示在质量选择器中
  • 所有<Representation>的timescale和duration必须一致,保证分片对齐

4. 可选但推荐的配置

  • 添加label属性到<Representation>:直接在质量选择器显示友好名称,比如<Representation label="1080p (2Mbps)" ...>
  • 为<AdaptationSet>添加role属性:明确标记音视频,比如<AdaptationSet role="main" ...>(视频)、<AdaptationSet role="main" audioChannelConfiguration="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" ...>(音频)
  • 启用ContentProtection:如果需要DRM,但不影响质量选择器的显示
工具链示例:用FFmpeg一键生成MPD和分片

手动写MPD容易出错,推荐用FFmpeg自动生成,以下是一个点播多码率DASH的命令:

ffmpeg -i input.mp4 \
  # 生成1080p视频流
  -c:v libx264 -crf 23 -preset medium -b:v 2M -s 1920x1080 -keyint_min 60 -g 60 \
  # 生成720p视频流
  -c:v libx264 -crf 23 -preset medium -b:v 1M -s 1280x720 -keyint_min 60 -g 60 \
  # 生成480p视频流
  -c:v libx264 -crf 23 -preset medium -b:v 500k -s 854x480 -keyint_min 60 -g 60 \
  # 音频流
  -c:a aac -b:a 128k \
  # DASH输出配置
  -f dash -use_template 1 -use_timeline 1 -seg_duration 4 \
  -adaptation_sets "id=0,streams=v id=1,streams=a" \
  output.mpd
  • -adaptation_sets参数把所有视频流放到同一个AdaptationSet(id=0),音频流放到另一个(id=1),完美适配dash.js的质量选择逻辑
  • -seg_duration 4设置分片时长为4秒,和之前的minBufferTime匹配
验证dash.js兼容性的小技巧
  1. 用dash.js的官方在线播放器(本地部署或官方demo)加载你的MPD,查看质量选择器是否出现
  2. 打开浏览器控制台,检查是否有MPD解析错误,如果有,根据提示修正MPD的配置
  3. 确保所有分片文件的路径正确,MPD中的initialization和media路径要和实际文件位置匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:35:42