如何用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兼容性的小技巧
- 用dash.js的官方在线播放器(本地部署或官方demo)加载你的MPD,查看质量选择器是否出现
- 打开浏览器控制台,检查是否有MPD解析错误,如果有,根据提示修正MPD的配置
- 确保所有分片文件的路径正确,MPD中的
initialization和media路径要和实际文件位置匹配
内容的提问来源于stack exchange,提问作者pesehr
相关产品推荐
相关产品推荐

