如何解析DASH流MPD文件获取分片与分辨率参数用于视频渲染及码率切换
DASH MPD文件解析及分片、参数获取方法
基础解析规则
你要的分辨率、分片信息都可以直接从MPD的XML标签属性里提取,核心规则如下:
- 分辨率、流标识、码率:从
<Representation>标签读取,id是流唯一标识,width/height对应视频宽高,bandwidth是码率(单位bps),codecs是编码格式。 - 分片信息:你给出的样例用的是
SegmentTemplate模板分片方案,读取以下属性即可:initialization:流初始化分片地址,播放任意码率的流都需要先请求该文件media:媒体分片模板,其中$Number$是分片序号占位符startNumber:分片起始序号,模板里的$Number$从该值开始递增- 单分片时长 =
duration/timescale,你的样例里单分片时长为 25008 / 24000 = 1.042秒
你提供的MPD片段解析
原始MPD片段
<SupplementalProperty schemeIdUri="urn:mpeg:dash:srd:2014" value="0,0,0,1,1,3,3"/> <Representation id="1" mimeType="video/mp4" codecs="hev2.1.6.L186.0" width="640" height="360" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="131694"> <SegmentTemplate timescale="24000" media="sequence_qp22_dash_track1_$Number$.m4s" startNumber="1" duration="25008" initialization="hevc_srd_set1_init.mp4"/> </Representation> </AdaptationSet> <AdaptationSet segmentAlignment="true" maxWidth="640" maxHeight="360" maxFrameRate="24" par="16:9" lang="und"> <SupplementalProperty schemeIdUri="urn:mpeg:dash:srd:2014" value="0,1,0,1,1,3,3"/> <Representation id="3" mimeType="video/mp4" codecs="avc1.4d401e" width="640" height="360" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="131424"> <SegmentTemplate timescale="24000" media="tile2-360p-128kbps_dash$Number$.m4s" startNumber="1" duration="25008" initialization="tile2-360p-128kbps_dashinit.mp4"/> </Representation> <Representation id="4" mimeType="video/mp4" codecs="avc1.4d401e" width="640" height="360" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="1492186"> <SegmentTemplate timescale="24000" media="tile2-360p-1500kbps_dash$Number$.m4s" startNumber="1" duration="25008" initialization="tile2-360p-1500kbps_dashinit.mp4"/> </Representation> </AdaptationSet> <AdaptationSet segmentAlignment="true" maxWidth="640" maxHeight="360" maxFrameRate="24" par="16:9" lang="und"> <SupplementalProperty schemeIdUri="urn:mpeg:dash:srd:2014" value="0,2,0,1,1,3,3"/> <Representation id="5" mimeType="video/mp4" codecs="avc1.4d401e" width="640" height="360" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="129740"> <SegmentTemplate timescale="24000" media="tile3-360p-128kbps_dash$Number$.m4s" startNumber="1" duration="25008" initialization="tile3-360p-128kbps_dashinit.mp4"/> </Representation> <Representation id="6" mimeType="video/mp4" codecs="avc1.4d401e" width="640" height="360" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="1451324"> <SegmentTemplate timescale="24000" media="tile3-360p-1500kbps_dash$Number$.m4s" startNumber="1" duration="25008" initialization="tile3-360p-1500kbps_dashinit.mp4"/> </Representation> </AdaptationSet>
解析后参数数组示例
你可以直接按如下结构整理参数,用于后续渲染或码率切换:
const dashStreamList = [ { id: "1", codec: "hev2.1.6.L186.0", resolution: "640x360", bandwidth: 131694, initSegmentUrl: "hevc_srd_set1_init.mp4", segmentTemplate: "sequence_qp22_dash_track1_$Number$.m4s", startSegmentNo: 1, segmentDuration: 1.042, srdTileX: 0 // 从SupplementalProperty的value第2位获取,用于拼接渲染 }, { id: "3", codec: "avc1.4d401e", resolution: "640x360", bandwidth: 131424, initSegmentUrl: "tile2-360p-128kbps_dashinit.mp4", segmentTemplate: "tile2-360p-128kbps_dash$Number$.m4s", startSegmentNo: 1, segmentDuration: 1.042, srdTileX: 1 }, { id: "4", codec: "avc1.4d401e", resolution: "640x360", bandwidth: 1492186, initSegmentUrl: "tile2-360p-1500kbps_dashinit.mp4", segmentTemplate: "tile2-360p-1500kbps_dash$Number$.m4s", startSegmentNo: 1, segmentDuration: 1.042, srdTileX: 1 }, { id: "5", codec: "avc1.4d401e", resolution: "640x360", bandwidth: 129740, initSegmentUrl: "tile3-360p-128kbps_dashinit.mp4", segmentTemplate: "tile3-360p-128kbps_dash$Number$.m4s", startSegmentNo: 1, segmentDuration: 1.042, srdTileX: 2 }, { id: "6", codec: "avc1.4d401e", resolution: "640x360", bandwidth: 1451324, initSegmentUrl: "tile3-360p-1500kbps_dashinit.mp4", segmentTemplate: "tile3-360p-1500kbps_dash$Number$.m4s", startSegmentNo: 1, segmentDuration: 1.042, srdTileX: 2 } ]
额外说明
你提供的MPD片段里包含urn:mpeg:dash:srd:2014的补充属性,这是DASH的空间区域描述标识,value字段的第2位是tile的X坐标,第3位是Y坐标,你的样例是3列1行的拼接流,渲染时需要把三个tile按X坐标从左到右拼接成完整画面。
功能实现方法
- 分辨率切换:根据当前网络带宽匹配对应
bandwidth的流,切换时先加载新流的初始化分片,再按当前播放进度计算对应分片序号,请求新流的对应媒体分片即可,无需从头播放。 - 生成分片地址:将
segmentTemplate里的$Number$替换为从startSegmentNo开始的递增整数,即可得到所有分片的完整地址。
内容的提问来源于stack exchange,提问作者穿拖鞋的小涵
相关产品推荐
相关产品推荐

