前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >冲顶大会有前端什么事吗?

冲顶大会有前端什么事吗?

作者头像
villainhr
发布于 2018-07-03 07:07:08
发布于 2018-07-03 07:07:08
1.8K00
代码可运行
举报
文章被收录于专栏:前端小吉米前端小吉米
运行总次数:0
代码可运行

最近的冲顶大会只是一个知识问答的模式,不过结合直播起来可能就带来不一样的效果了。总的来看主要火起来的有几个基本点:

  • 低门槛:人人都可以答题
  • 奖金高:差不多都是百万以上,但是不排除机器人和你分钱 :)
  • 延时低:同时出题,同时答题。这点对于延时直播来说,压力非常大,差不多延时必须控制到 2s 之内。所以,HLS 基本上就凉了。
  • KOL 带节奏,比如王思聪 撒币
  • 主播美眉
  • 。。。

作为一个前端开发来说,我觉得直播的世界离我们太遥远,其中有两座大山,一个是 X5 ,一个是 苹果。因为,X5 和苹果这逼不提供 MSE 给前端用,导致了一个结果,要么用 HLS 直播,要么你就不播。现在,鄙人正在腾讯打工,最近和 X5 杠上了,问他们为什么不支持 MSE?他们给的答复是:

可以说,在明年,MSE 技术应该会让前端能力得到极大的扩展。但是,MSE 只是作为一个播放端的技术,流从哪里来?H5 直播是怎么搞的?

对于一些基础知识,推荐大家直接去这篇文章里面查看:

https://www.villianhr.com/2017/03/31/全面进阶 H5 直播

现阶段,比较流行的协议主要有:HLS,RTMP,HTTPFLV。延时性就属 HLS 最菜,这是苹果自研直播流播放器,差不多播放延时有 10s+ 左右。而 RTMP 和 HTTPFLV 都和 Adobe 公司有点关系,这有种让人离不开 Flash 的感觉,他们俩的延时性都出奇的好,差不多只有 3s 左右,但是里面流确实 FLV 格式的。

但是,W3C 不同意,老子绝壁不想和 Flash 再有半点关系,我现在有 WebM,FMP4,TS 凭啥再去迁就你的 FLV?

为了从源头解决这个问题,MPEG 推出了 MPEG-DASH 直播标准来统一各种比较尴尬的流描述文件。它主要是基于 mpd 文件来做的切片和文件的 download。先来看一份简单的 MPEG-DASH 文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple" maxSegmentDuration="PT2S" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT10S">
   <ProgramInformation>
      <Title>Media Presentation Description from DASHI-IF live simulator</Title>
   </ProgramInformation>
   <BaseURL>http://vm2.dashif.org/dash/vod/testpic_2s/</BaseURL>
   <Period id="precambrian" start="PT0S">
      <AdaptationSet contentType="audio" mimeType="audio/mp4" lang="eng" segmentAlignment="true" startWithSAP="1">
         <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
         <SegmentTemplate startNumber="1" initialization="$RepresentationID$/init.mp4" duration="2" media="$RepresentationID$/$Number$.m4s"/>
         <Representation id="A48" codecs="mp4a.40.2" bandwidth="48000" audioSamplingRate="48000">
            <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
         </Representation>
      </AdaptationSet>
      <AdaptationSet contentType="video" mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" par="16:9" minWidth="640" maxWidth="640" minHeight="360" maxHeight="360" maxFrameRate="60/2">
         <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
         <SegmentTemplate startNumber="1" initialization="$RepresentationID$/init.mp4" duration="2" media="$RepresentationID$/$Number$.m4s"/>
         <Representation id="V300" codecs="avc1.64001e" bandwidth="300000" width="640" height="360" frameRate="60/2" sar="1:1"/>
      </AdaptationSet>
   </Period>
</MPD>

基本原理是,后台将一份完整的流文件切片,生成 Initial Segment 和 Media Segments,这些就是流的片段文件,比如 .mp4.ts等。更详细的内容,下面会进行详述。

那该协议的延时性怎么样呢?

这个主要取决于你的协议,最极致的时延是比 HTTP-FLV 还要快,差不多 <= 2~3s。其中,最主要的是它定义的模板解析机制,直接根据时间戳来协定。

MPD 基本简介

DASH 其实只是一系列概念,原意是 DynamicAdaptiveStreamingover HTTP。它主要是基于 mpd 文件来做的切片和文件的 download。整个模式有点类似于 HLS,但是其可以应用于所有的 视频格式,比如 mp4,webm。它将整个的视频文件,切片分为一个个具体的 HTTPFLV segments。不过,其更优于 HLS,这个已经在上面阐述清楚了。

MPD 的播放模式,其实就是根据 XML 的内容,协商出来播放的切片 URL 地址。一个简易的 MPD 文件为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<MPD availabilityStartTime="1970-01-01T00:00:00Z" id="Config part of url maybe?" maxSegmentDuration="PT2S" minBufferTime="PT2S" minimumUpdatePeriod="P100Y" profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple" publishTime="2018-01-06T06:57:00Z" timeShiftBufferDepth="PT5M" type="dynamic" ns1:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" 
      xmlns="urn:mpeg:dash:schema:mpd:2011" 
      xmlns:ns1="http://www.w3.org/2001/XMLSchema-instance">
      <ProgramInformation>
            <Title>Media Presentation Description from DASHI-IF live simulator</Title>
      </ProgramInformation>
      <BaseURL availabilityTimeOffset="10.000000">https://vm2.dashif.org/livesim-dev/ato_10/testpic_2s/</BaseURL>
      <Period id="p0" start="PT0S">
            <AdaptationSet contentType="audio" lang="eng" mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1">
                  <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
                  <SegmentTemplate duration="2" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="0" />
                  <Representation audioSamplingRate="48000" bandwidth="48000" codecs="mp4a.40.2" id="A48">
                        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />
                  </Representation>
            </AdaptationSet>
            <AdaptationSet contentType="video" maxFrameRate="60/2" maxHeight="360" maxWidth="640" mimeType="video/mp4" minHeight="360" minWidth="640" par="16:9" segmentAlignment="true" startWithSAP="1">
                  <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
                  <SegmentTemplate duration="2" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="0" />
                  <Representation bandwidth="300000" codecs="avc1.64001e" frameRate="60/2" height="360" id="V300" sar="1:1" width="640" />
            </AdaptationSet>
      </Period>
</MPD>

XML 文件里面的每一个标签内容,都是遵循 MPEG-DASH LA 的标准。其内部包含 N+1 个 Periods Tag。每一个 Period 包含相关的 media stream,比如 video:不同的编码,视角,带宽等、 audio:不同语言,类型,带宽等。一些共同的参数,比如 codec,frame rate, audio-channel 在同一个 Period 是不能改变的。所以,尽可能在一个 Period 提供更丰富的描述信息来说是非常重要的。虽然,Period 里面的信息不能动态改变,但是,用户可以自己手动选择,自己想要的分辨率,带宽大小等等。

Period 可以包含多个流,所以,还可以提供插入广告,或者视角流的切分等功能。这个也是 MPEG-DASH 设计的初衷,通过一份文件协商出多个媒体流的内容。其基础架构内容为:

这里,我们先简单介绍一下,几个重点 TAG 具体的内容。

MPD

该是 MPD 里面文件的最外层的 Tag,有相关的属性来对其进行描述。该标签里面的属性极为重要,它决定了该 MPD 描述的文件属性和 媒体流 的播放顺序和内容。

再说三遍: MPD 文件非常重要! MPD 文件非常重要! MPD 文件非常重要!

其基本属性为:

接下来,我们一个一个简单介绍一下:

  • id: 设置 MPD 的 identifier,一般不需要。
  • profiles: 设置 MPD 的基本标准,具体内容,参考下表 profles。
  • type: 用来设置 MPD 文件的基本属性。取值有两个
    • static:segment 的时长需要在 @availabilityStartTime 和 @availabilityEndTime 之间。
    • dynamic:主要根据 availabilityStartTime 时间决定。
  • availabilityStartTime: 设置所有 segment 的参考时间,如果 type 为 dynamic,则该属性是必须的。
  • availabilityEndTime: 对于 static 文件来说的静态文件范围。
  • pulishTime: 设置 MPD 文件生成的绝对时间(wall-clock)
  • mediaPresentationDuration: 设置当前 mediaSegments 的总时间长。例如 PT20M,表示时长为 20min。当 MPD.minimumUpdatePeriod 和 Period.duration 没有设置时,该属性可以作为替代。
  • minimumUpdatePeriod: 设置当前 MPD 文件的更新时间。当 type = static 时,该属性不应该出现。
  • minBufferTime:用来设置最小 segment 时长,例如: PT2S。该通常和 Representation.bandwidth(bps) 一起使用,来计算最小 segment 大小值。
  • timeShiftBufferDepth: 用来设置 MPD 中 segment 的有效区间。或者可以理解为 过期时间。这里,后面我们会详述一下。
  • maxSegmentDuration: 设置最大 segment 时长。

上面我们已经了解 MPD 标签里面的基本属性,这些属性在整个 MPEG-DASH 里面非常重要,后面,我们将简单讲解一下关于 MPD 更新和文件过期的点。

MPD 文件更新机制

MPD 文件的更新主要取决于 @minimumUpdatePeriod 属性设置,例如: minimumUpdatePeriod="PT10S"。用来标识,MPD 文件从上一次 MPD 获取时间开始,10s 后检查一次更新。如果没有该属性,或者为 0,则代表该 MPD 文件不会过期。整个更新逻辑为:

那当 MPD 文件发生更新时,有一些内容需要注意:

  • MPD.id 属性值必须和以前的 MPD 一致
  • Period.id 属性必须和以前的 Period 一致
  • MPD.publishTime 需要和更新时间一致

更详细的内容,可以参考 ISO/ITU 官方标准 5.4MediaPresentationDescriptionupdates

Segment 文件过期

特别针对于直播切片文件来说,由于服务器容量有限,所以,并不会一直被保存在服务器当中。最好的办法就是协定对应 Segment 的过期时间。那这个过期时间是怎么确定的呢?

主要根据以下公式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[max(AST, now-timeShiftBufferDepth), now]
  • AST:是 MPD.availabilityStartTime 属性.
  • timeShiftBufferDepth: 是 MPD.timeShiftBufferDepth 属性,用来协定过期时间。

因为通常情况, max(AST,now-timeShiftBufferDepth)=now-timeShiftBufferDepth。所以,上面的范围可以精简为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
now-timeShiftBufferDepth <= time <= now

整个时长区间是由 MPD.timeShiftBufferDepth 属性值来控制的。例如,MPD 标签的设置值为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
timeShiftBufferDepth="PT5M"

那么,文件有效期范围为,具体最新 MPD 文件 publishTime 前 5min 之内的链接是有效的。

Period

Period 主要是用来包含具体 流媒体 的数据,其本身只是起到设置 startTime 和区分多个 Period@id 的作用。它的基本属性没有多少:

这里,我直接用文本的形式表达一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xs:sequence>
    <xs:element name="BaseURL" type="BaseURLType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="SegmentBase" type="SegmentBaseType" minOccurs="0"/>

    <xs:element name="SegmentList" type="SegmentListType" minOccurs="0"/> 
    <xs:element name="SegmentTemplate" type="SegmentTemplateType" minOccurs="0"/> 
    <xs:element name="AssetIdentifier" type="DescriptorType" minOccurs="0"/>

    <xs:element name="EventStream" type="EventStreamType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="AdaptationSet" type="AdaptationSetType" minOccurs="0" maxOccurs="unbounded"/>
    <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="xlink:href"/>
<xs:attribute ref="xlink:actuate" default="onRequest"/>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="start" type="xs:duration"/>
<xs:attribute name="duration" type="xs:duration"/>
<xs:attribute name="bitstreamSwitching" type="xs:boolean" default="false"/> 
<xs:anyAttribute namespace="##other" processContents="lax"/>

对于 Period 我们主要关注一下 attribute 属性内容。

  • id: 用来标识 Period 的唯一性。如果 MPD.type= dynamic,则该 id 不会在 MPD 更新时改变。
  • start: 用来设置 Period 下,Segment 参考的开始时间。不过,该 start 的确定并不是根据本身的 Period 来决定,还需要根据前一个 Period 来确定:
    • 如果当前的 Period 没有 start 属性,但是前一个 Period 是正常的,有 start 和 duration 属性。那么当前的 Period.start=prevPeriod.start+prevPeriod.duration
    • 如果当前的 Period 没有 start 属性, MPD.type=static,该 Period 是该 MPD 第一个出现的 Period 标签,那么 start 值默认会被设置为 0
  • duration: 用来决定当前 Period 的时长
  • bitstreamSwitching: 是否允许改变切流,默认为 false。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Period id="p0" start="PT0S">
    // ...
  </Period>

AdapationSet

AdaptionSet 主要是用来对当前包含的流进行基本信息的表述,相当于 MP4 中的 ftype+moof box 信息。

主要属性如下,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xs:sequence>

    <xs:element name="Accessibility" type="DescriptorType" minOccurs="0" maxOccurs="unbounded"/>

    <xs:element name="Role" type="DescriptorType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="Rating" type="DescriptorType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="Viewpoint" type="DescriptorType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="ContentComponent" type="ContentComponentType" minOccurs="0" maxOccurs="unbounded"/>

    <xs:element name="BaseURL" type="BaseURLType" minOccurs="0" maxOccurs="unbounded"/> 
    <xs:element name="SegmentBase" type="SegmentBaseType" minOccurs="0"/>

    <xs:element name="SegmentList" type="SegmentListType" minOccurs="0"/>

    <xs:element name="SegmentTemplate" type="SegmentTemplateType" minOccurs="0"/> 
    <xs:element name="Representation" type="RepresentationType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
    <xs:attribute ref="xlink:href"/>
    <xs:attribute ref="xlink:actuate" default="onRequest"/> <xs:attribute name="id" type="xs:unsignedInt"/> 
    <xs:attribute name="group" type="xs:unsignedInt"/> <xs:attribute name="lang" type="xs:language"/> 
    <xs:attribute name="contentType" type="xs:string"/> <xs:attribute name="par" type="RatioType"/>
    <xs:attribute name="minBandwidth" type="xs:unsignedInt"/> <xs:attribute name="maxBandwidth" type="xs:unsignedInt"/> 
    <xs:attribute name="minWidth" type="xs:unsignedInt"/> <xs:attribute name="maxWidth" type="xs:unsignedInt"/> 
    <xs:attribute name="minHeight" type="xs:unsignedInt"/> <xs:attribute name="maxHeight" type="xs:unsignedInt"/> 
    <xs:attribute name="minFrameRate" type="FrameRateType"/> <xs:attribute name="maxFrameRate" type="FrameRateType"/>
    <xs:attribute name="segmentAlignment" type="ConditionalUintType" default="false"/> 
    <xs:attribute name="subsegmentAlignment" type="ConditionalUintType" default="false"/> 
    <xs:attribute name="subsegmentStartsWithSAP" type="SAPType" default="0"/> 
    <xs:attribute name="bitstreamSwitching" type="xs:boolean"/>

看图会不会更清晰:

这些属性,我就不一一多说了,大家看一个 Demo 理解一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<AdaptationSet contentType="video" maxFrameRate="60/2" maxHeight="360" maxWidth="640" mimeType="video/mp4" minHeight="360" minWidth="640" par="16:9" segmentAlignment="true" startWithSAP="1">
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
    <SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/t$Time$.m4s" timescale="90000">
        <SegmentTimeline>
            <S d="180000" r="150" t="136377021600000" />
        </SegmentTimeline>
    </SegmentTemplate>
    <Representation bandwidth="300000" codecs="avc1.64001e" frameRate="60/2" height="360" id="V300" sar="1:1" width="640" />
</AdaptationSet>

这里的描述信息,并不只局限于 AS(AdaptionSet) 一个属性,还可以用在 Representation 上。

Representation

Representation 是嵌套在 AS 里面,它也是流的相关描述信息,其实也就相当于是一个 IS(Initial Segment)。

主要信息有:

主要用法就是给当前的流提供基本描述信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Representation bandwidth="300000" codecs="avc1.64001e" frameRate="60/2" height="360" id="V300" sar="1:1" width="640" />

指定 Rep(Representation)的生效范围是在当前的 Period 的范围之内,也就是从: Period.start-Period.endTime。Rep 的描述信息为了使用率最大,被 Rep 包含的 Stream 都可以用该内容作为描述信息。

另外,我们还可以结合 dependencyIdid 来重复利用 Rep 的内容。通过 dependencyId 指定模板 Rep@id,实现信息的直接复用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Representation bandwidth="300000" codecs="avc1.64001e" frameRate="60/2" height="360" id="1" sar="1:1" width="640" />

<Representation dependencyId="1" id="2" mimeType="video/mp4" />

MPD 如何表达 Segments

在 MPD 中,描述 Segments 主要由 SegmentBase,SegmentTemplateandSegmentList。一个完整的 Rep 需要:

  • N+1 SegmentList 标签
  • 1 SegmentTemplate
  • N+1 BaseURL 标签,[0,1] SegmentBase,没有 SegmentTemplate 和 SegmentList 标签。

这里,我们简单描述一下对应 Segment tag 的内容。

SegmentBase

SegmentBase 只在 static MPD 文件中使用,其基本内容其实是几个 Segments tag 共享内容,基本属性为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xs:sequence>
<xs:element name="Initialization" type="URLType" minOccurs="0"/>
<xs:element name="RepresentationIndex" type="URLType" minOccurs="0"/>
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="timescale" type="xs:unsignedInt"/>
<xs:attribute name="presentationTimeOffset" type="xs:unsignedLong"/>
 <xs:attribute name="timeShiftBufferDepth" type="xs:duration"/>
 <xs:attribute name="indexRange" type="xs:string"/>
<xs:attribute name="indexRangeExact" type="xs:boolean" default="false"/>
 <xs:attribute name="availabilityTimeOffset" type="xs:double"/>
 <xs:attribute name="availabilityTimeComplete" type="xs:boolean"/>


 // extension prop
 <xs:extension base="SegmentBaseType">
   <xs:sequence>
    <xs:element name="SegmentTimeline" type="SegmentTimelineType" minOccurs="0"/>
    <xs:element name="BitstreamSwitching" type="URLType" minOccurs="0"/> 
   </xs:sequence>
    <xs:attribute name="duration" type="xs:unsignedInt"/>
    <xs:attribute name="startNumber" type="xs:unsignedInt"/>
</xs:extension>

如果觉得不清楚,可以看这张图:

![image.png-194.7kB][108]

Initialization Tag 可以作为元素,也可以直接作为 Segments Tag 的属性,来设置 Initial Segment 的 URL 链接。基本设置为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<BaseURL>v-0144p-0100k-libx264.mp4</BaseURL>
 <SegmentBase indexRange="678-1597" timescale="12288">
    <Initialization range="0-677"/>
</SegmentBase>

indexRange 设置 media Segment 的字节范围,range 则设置 Initial Segment 的字节范围。

另外,还有几个属性比较重要:

  • presentationTimeOffset:设置当前 Segment 相对于 Period 开始的偏移时间。
  • timeShiftBufferDepth:默认覆盖 MPD 的属性,并且该值不能比 MPD 的小。
  • availabilityTimeOffset:设置当前 Segment 可以获得的时间偏移量。

不过,在实际使用时,使用 SegmentBase 的情况很少,大家对其有印象即可。

SegmentList

该标签是用来标识一整套 Segment 的 URL list 内容。具体内容信息可以参考:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xs:element name="SegmentURL" type="SegmentURLType" minOccurs="0" maxOccurs="unbounded"/>

<xs:attribute name="media" type="xs:anyURI"/>
<xs:attribute name="mediaRange" type="xs:string"/>
<xs:attribute name="index" type="xs:anyURI"/>
<xs:attribute name="indexRange" type="xs:string"/>

主要内容为:

该 Tag 常常用来包含一个完整的视频 List 内容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<SegmentList timescale="90000" duration="5400000">
       <RepresentationIndex sourceURL="representation-index.sidx"/>
       <SegmentURL media="segment-1.ts"/>
       <SegmentURL media="segment-2.ts"/>
       <SegmentURL media="segment-3.ts"/>
       <SegmentURL media="segment-4.ts"/>
       <SegmentURL media="segment-5.ts"/>
       <SegmentURL media="segment-6.ts"/>
       <SegmentURL media="segment-7.ts"/>
       <SegmentURL media="segment-8.ts"/>
       <SegmentURL media="segment-9.ts"/>
       <SegmentURL media="segment-10.ts"/>
</SegmentList>

SegmentTemplate

SegmentTemplate 主要应用在文件切片数量过于庞大,如果使用 SegmentList 标签,则有点得不偿失。对于一些 live scenarios,比如直播,连麦等等。使用 SegmentTemplate 应该是非常有用的。它可以通过 startNumber,以及对应的 模板URL,来提供给客户端进行相关链接解析。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Representation mimeType="video/mp4"
                   frameRate="24"
                   bandwidth="1558322"
                   codecs="avc1.4d401f" width="1277" height="544">
  <SegmentTemplate media="http://cdn.bitmovin.net/bbb/video-1500/segment-$Number$.m4s" 
  initialization="http://cdn.bitmovin.net/bbb/video-1500/init.mp4" 
  startNumber="0" 
  timescale="24" 
  duration="48"/>
</Representation>

具体属性内容为:

  • index: 对于 Template 字段,对 \$Number\$ 和 \$Time\$ 标识符进行替换。
  • initialization: 用来标识 Initialization Segment 的具体地址,在该属性里面只能使用标识符\$RepresentationID\$。

使用 template 的方式,能够很大的减小 MPD 文件大小,不过会额外增加以下客户端解析 MPD 的时间。除了上面使用 $Number$ 形式进行解码外,还可以使用 $RepresentationID$ 的标识符来进行字符替换:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<SegmentTemplate
    duration="2"     
    initialization="$RepresentationID$/init.mp4"
    media="$RepresentationID$/$Number$.m4s" 
    startNumber="0" />
<Representation 
    bandwidth="300000" 
    codecs="avc1.64001e" 
    frameRate="60/2" 
    height="360" 
    id="V300" 
    sar="1:1" 
    width="640" />

那一共有哪些标识符可以使用呢?在哪些标签里面才能使用这些标识符呢?我们简单描述一下:

Identifier 用途

Identifier 常常用在 SegmentTemplate 标签中,只有以下属性可以使用标识符: media, index, initializationbitstreamSwitching 属性。

  • \$RepresentationID\$: 对应于 Representation 标签中的 id 属性,比如上面就是 V300。。。

完整标识符解释内容,可以关注公众号:前端小吉米,输入:MPD.identifier 获取。

SegmentTimeline

SegmentTimeline 里面会通过多个 S 标签,来标识在同一个 MPD duration 内的 Segment 内容。也就是说,SegmentTimeline 只是提供了一个模板容器,具体的流的标识还是由 S 标签内容来决定。直接看一个最简单的 ST(SegmentTimeline):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<SegmentTimeline timescale="1000">
    <S t="0" r="10" d="24000"/>
</SegmentTimeline>

这里,我们先来看一下 S 标签下的基本属性值:

  • t:标识当前 Segment 在 Period 流中开始时间。一般来说,不用设置即可。如果设置了,则其值为 previous S@t+@d*(@r+1)。就是之前一个 S 标签的结束时间戳。
  • d:标识当前 Segment 的 duration
  • r:设置当前的 Segment 出现的个数。

我们来看一个 DEMO:

DEMO 详细解释和说明,可以关注:前端小吉米,输入:MPD.timeline 获取。

后续还有另外一篇,深入理解 DASH 直播的文章。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小吉米 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
技术解码 | DASH协议直播应用
导语 | 本文介绍了DASH协议,并分享了腾讯云直播系统在DASH协议功能实现和灰度验证中积累的经验、遇到的问题以及解决的思路。 - 协议介绍 - 在对海外各大OTT流媒体平台的调研中,我们可以了解到海外流媒体常用的协议有Facebook、Twitch等平台使用的、由Apple提出的HLS协议,微软在其名下各个平台上使用的、由其制定的MSS协议以及Adobe为各大企业提供媒体服务支持时使用的、其制定的HDS协议等等。 因此在海外音视频领域的流媒体协议应用中,各种协议五花八门。而为了在
腾讯云音视频
2021/11/01
6.4K0
Using XPaths in Message Assignment[转]
Microsoft BizTalk Server 2004 Using XPaths in Message Assignment You can use the xpath function to assign an XPath value to a message part, or to assign a value to an XPath that refers to a message part. For more information on assigning to messages and me
阿新
2018/04/12
7250
原来爱优腾等视频网站都是用这个来播放流媒体的
HLS (HTTP Live Streaming) 是苹果公司开发的流媒体传输协议,它使用 HTTP 来传输视频,可以防止被防火墙屏蔽。现在大部分视频网站都在使用,比如优酷、腾讯视频。
lcyw
2022/11/23
1.8K0
原来爱优腾等视频网站都是用这个来播放流媒体的
Easy Tech:什么是MPEG-DASH协议
点击上方“LiveVideoStack”关注我们 翻译 | Alex 技术审校 | 赵军 本文来自OTTVerse,作者为Krishna Rao Vijayanagar。 MPEG-DASH Easy Tech #014# MPEG-DASH是最流行的视频流协议之一,它广泛用于点播和直播,将媒体传输给各种终端设备,包括手机、平板、智能电视、游戏机等。MPEG-DASH是一种基于HTTP的流媒体传输协议,负责将视频从HTTP服务器传输给终端用户。在MPEG-DASH中,一个视频被分割成许多切片,这一信息被一个
LiveVideoStack
2022/03/04
2.1K0
dash.js:流媒体的发展故事
如果想要阐述一些科学知识,把这件事情当作是讲故事不失为一个好方法,所以我选择在这次的演讲中做同样的事情,将这次的演讲题目取名为“一个流媒体发展的故事”。
用户1324186
2021/11/23
2.3K0
FMP4与DASH的概念理解
DASH:Dynamic Adaptive Streaming over HTTP
呱牛笔记
2023/05/02
1.7K0
FMP4与DASH的概念理解
实时低延迟流式传输
本文来自BITMOVIN,由Jameson Steiner编辑,文章主要内容是“实时低延迟流式传输”。
用户1324186
2020/07/07
2.4K0
EME WTF? 加密媒体扩展介绍
加密媒体扩展提供了一个API,允许web应用与内容保护系统交互,允许播放加密的音频和视频。
gnip
2020/11/03
2.1K0
[Java拾遗一] XML的书写规范与解析.
前言 今天天气大好, 起了个大早开始总结一些常用的基础知识. XML一直来说都很陌生, 使用大多是用于配置文件, 之前并没有细究过其中的约束规范, 今天刚好没事来学习并总结下.  ---- 1,XML基础介绍   XML 指可扩展标记语言(EXtensible Markup Language),也是一种标记语言,很类似 HTML.它的设计宗旨是传输数据,而非显示数据它;标签没有被预定义,需要自行定义标签。   xml的作用:     XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描
一枝花算不算浪漫
2018/05/18
1.6K0
Oozie分布式任务的工作流——Spark篇
Spark是现在应用最广泛的分布式计算框架,oozie支持在它的调度中执行spark。在我的日常工作中,一部分工作就是基于oozie维护好每天的spark离线任务,合理的设计工作流并分配适合的参数对于spark的稳定运行十分重要。 Spark Action 这个Action允许执行spark任务,需要用户指定job-tracker以及name-node。先看看语法规则: 语法规则 <workflow-app name="[WF-DEF-NAME]" xmlns="uri:oozie:workflow:0.3
用户1154259
2018/01/17
1.3K0
Google Widevine及其工作原理
 点击上方“LiveVideoStack”关注我们 翻译、编辑:Alex 技术审校:刘姗 本文来自OTTVerse,作者为Krishna Rao Vijayanagar。 ▲扫描图中二维码或点击阅读原文▲ 了解音视频技术大会更多信息 Widevine DRM Easy-Tech #018# Google Widevine是一种常用的DRM解决方案,支持Android操作系统、多种智能电视、浏览器等。Widevine还支持MPEG-DASH、HLS、MSS以及CENC和CMAF,这种广泛的支持使它成
LiveVideoStack
2022/03/25
4.2K0
Java之XML的使用「建议收藏」
一.xml的定义和优势: (1).定义: 在描述一些有结构性的数据时应当使用XML来描述,例如:用户信息/省市结构等 XML(eXtensible Markup Language),是一种可扩展的标记语言,类似HTML。 XML技术是W3C组织(World Wide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于1998年发布的XML1.0规范。 HTML: 显示页面,网页. 学习里面自带的标签 XML: 传输数据,而非显示数据/少量数据存储。 XML标签没有被预定义,需要用户自行定义标签。
全栈程序员站长
2022/09/08
5620
Java之XML的使用「建议收藏」
ExoPlayer 自适应流切换分析
自适应流切换属于多路流切换的方式中的一种,ExoPlayer作为MediaCodec使用的集大成者,不仅具备通过MergingMediaSource实现不同流的组合切换,同样也具备基于MGEG-DASH、HLS、smoothing-stream 协议的的自适应流切换。当然,在项目中每种方案的选型都要充分考虑团队条件。
QQ音乐技术团队
2023/10/23
1.8K0
ExoPlayer 自适应流切换分析
XML Schema <第三篇>
  验证XML文档是否符合议定的XML结构有两种方法,分别是DTD模式与XML Schema。本文主要介绍XML Schema。
全栈程序员站长
2021/12/23
1.5K0
XML Schema <第三篇>
Shell解析处理XML方法汇总
前几天干活的时候遇到一个需要解析处理xml文件的一个需求,当时考虑到逻辑比较复杂,因此用java慢慢搞了搞。不过这个需求经常会变,每次变化之后都要重新找到jar包的代码,改了之后还要替换原来的jar包,一来不方便修改,二来不方便统一保存代码,三来也不方便查看jar包的功能。 其实对于这种比较灵活的功能,最方便高效的做法是采用一些脚本语言,比如python,ruby等等,开发效率高,而且也能处理一些复杂逻辑。但是由于种种原因,工作中有的机器没有安装这些语言的解释器。因此不得已,研究了一波用shell脚本解析xml的方法。 说到底,shell还是不太适合处理复杂的逻辑,但是对于一些简单的查找替换等需求,用shell来搞还是挺方便的。 我这里主要采用了下面三个工具:
mythsman
2022/11/14
3.2K0
为自定义配置的编辑提供”智能感知”的支持
当我们在设计一个框架的时候,必然会涉及一系列的配置。为了让使用者更好地使用你提供的框架,让他们能够容易地维护这些配置是一项基本的要求。对于一些配置过于复杂的框架,比如EnterLib,比如WCF,往往会提供一个配置的工具。但是,不过这样的配置工具是否提供,手工编译配置文件是在所难免的。如果在通过VS编辑配置的时候,能够提供智能感知和提示性描述的支持,这无疑会使配置的编辑变得非常的容易。这里是一个简单的例子。 一、配置文件的结构 假设我们设计一个MessageGenerator的组件,用于生成程序我们需要的文
蒋金楠
2018/02/07
7190
为自定义配置的编辑提供”智能感知”的支持
RTSP 媒体协议流的录制方案及其覆盖策略详解(上)
【自我介绍】大家好,我是 Data-Mining,别名 liuzhen007,中国邦德,一个敲代码的邦德,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对WebRTC、FFmpeg和Electron有非常深入的了解。
liuzhen007
2021/06/29
1.9K0
MPEG-DASH视频传输中的常见问题
 点击上方“LiveVideoStack”关注我们 作者:Daniel Silhavy、Stefan Pham 翻译:Alex 技术审校:张博 ▲扫描图中二维码或点击阅读原文▲ 了解音视频技术大会更多信息 ---- 作为dash.js项目的首席开发人员,我们经常面对这样的情况:我们必须评估DASH传输失败是由dash.js播放器实现中的实际bug引起,还是由错误的内容生成引起。在本文中,我们将分享一些在DASH传输中出现的常见错误,以及我们通常在面对这些错误时所总结的一些见解。 / DRM的特定问题
LiveVideoStack
2022/05/30
1.6K0
MPEG-DASH视频传输中的常见问题
HLS直播协议详解
首先我们先使用 ffmepg 对一段视频文件进行切片,视频所在路径:D:\Work\test
Gnep@97
2023/10/29
1.6K0
HLS直播协议详解
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
在本篇文章上一部分Order Processing的例子中,我们看到原本已Collection形式定义的DetailList属性(public IList<TDetail> DetailList),在Data Contract中却以Array的方式体现(public OrderDetail[] DetailList)。我们现在就来详细地讨论一下基于Collection & Dictionary 的Data Contract。 Data Contract for Collection 我们照例用例子来说
蒋金楠
2018/01/16
7050
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
相关推荐
技术解码 | DASH协议直播应用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文