什么是流媒体
流媒体(streaming media)是指采用流式传输技术在网络上连续实时播放的媒体格式,如音频、视频或多媒体文件,采用流媒体技术使得数据包得以像流水一样发送, 如果没有流媒体技术, 那么我们就要像以前用迅雷下电影一样, 下载整个影片才能观看, 讲DASH之前先简单介绍一下常用的直播协议: HLS, RTMP, HDS协议. 因为DASH协议其实就是组合了以前的一些技术而发展出来的.
1. RTMP
RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议。是我们市面上绝大多数部分PC秀场使用的技术栈, 他有低延迟(2秒左后), 稳定性高, 技术完善, 高支持度, 编码兼容性高等特点.
RTMP的整体流程
2. HTTP-FLV
FLV (Flash Video) 是 Adobe 公司推出的另一种视频格式,是一种在网络上传输的流媒体数据存储容器格式。HTTP-FLV 即将流媒体数据封装成 FLV 格式,然后通过 HTTP 协议传输给客户端。HTTP-FLV这种方式较RTMP协议好的就是它采用公共的HTTP80端口, 有效避免被防火墙拦截, 可以通过 HTTP 302 跳转灵活调度/负载均衡,支持使用 HTTPS 加密传输,但它也有缺点, 视频的内容会缓存到用户本地, 保密性不好. HTTP-FLV的整体流程和RTMP协议一致, 但在客户端播放有些差异, 在MSE出现以前市场上一般都是用flash播放器去播放, MSE出现以后以及推广HTML5播放器的原因, 市场上开始使用JS软解FLV的方式, 通过HTMLVideoElement去播放.
3. HLS协议
HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。是苹果公司QuickTime X和iPhone软件系统的一部分, HLS支持MPEG-2 TS标准(WWDC16 苹果宣布支持 Fragmented MP4), 移动端支持良好, 现在已经成为移动端H5直播的主要技术, 它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。主要是为了解决RTMP协议存在的一些问题, 比如RTMP协议不使用标准的HTTP接口传输数据(TCP、UDP端口:1935),所以在一些特殊的网络环境下可能被防火墙屏蔽掉。但是HLS由于使用的HTTP协议传输数据(80端口),不会遇到被防火墙屏蔽的情况.
HLS的整体流程
客户端播放HLS流时的情况
index.m3u8文件的构成
协议对比
4. HDS
Http Dynamic Streaming(HDS)是一个由Adobe公司模仿HLS协议提出的另一个基于Http的流媒体传输协议。其模式跟HLS类似,但是又要比HLS协议复杂一些,也是索引文件和媒体切片文件结合的下载方式。
在服务器端降一个视频文件分割成segment节,segment节表示的是这个视频的几种不同的分辨率模式,针对某种分辨率的segment节,可以再划分成fragmen片段,每个片段都是视频的一小段时间,分段后每个片段会有segment+fragment的索引,客户端会根据索引请求视频片段。索引文件可以是.f4m的manifest文件,也可以是.bootstrap文件,视频文件是使用附加的基于标准的MP4片段格式(ISO / IEC 14496-12:2008)扩展F4V格式,扩展名为.f4f。
HDS的流程图
1.客户端向Web服务器发送一个HTTP请求,例如http://www.example.com/media/httpdynamicStreaming.f4m。
2.服务器将收到的请求传递给HTTP Origin Module。
3.HTTP Origin Module将描述文件(F4M)返回到客户端。
4.客户端收到描述文件(F4M),根据 bootstrap中的信息中的传送时间,组成一个segment#/fragment#对。
5.然后客户端解析F4M的内容向服务器发送一个请求,比如http://www.example.com/media/httpdynamicStreamingSeg1-Frag1(segment中的fragmen片段)或者http://www.example.com/media/httpdynamicStreamingSeg1.f4f。(segment)
6.服务器返回相应的视频片段。
7.客户端接收分片,处理之后播放。
DASH协议
DASH(MPEG-DASH)是 Dynamic Adaptive Streaming over HTTP的缩写,是国际标准组 MPEG 2014年推出的技术标准, 主要目标是形成IP网络承载单一格式的流媒体并提供高效与高质量服务的统一方案, 解决多制式传输方案(HTTP Live Streaming, Microsoft Smooth Streaming, HTTP Dynamic Streaming)并存格局下的存储与服务能力浪费、运营高成本与复杂度、系统间互操作弱等问题.
DASH是基于HTTP的动态自适应的比特率流技术,使用的传输协议是TCP(有些老的客户端直播会采用UDP协议直播, 例如YY, 齐齐视频等). 和HLS, HDS技术类似, 都是把视频分割成一小段一小段, 通过HTTP协议进行传输,客户端得到之后进行播放;不同的是MPEG-DASH支持MPEG-2 TS、MP4等多种格式, 可以将视频按照多种编码切割, 下载下来的媒体格式既可以是ts文件也可以是mp4文件, 所以当客户端加载视频时, 按照当前的网速和支持的编码加载相应的视频片段进行播放.
DASH的整个流程
-
主播直播流上传
-
服务器的编解码封装
-
流媒体分发器
-
mpd文件
-
切割后的媒体文件
-
-
客户端
-
客户端加载mpd文件
-
解析MPD文件, 组成文件下载链接
-
当前的网速和支持的编码加载相应的视频片段进行播放
-
MPD文件内容
MPD文件构成
-
MPD 标签
属性:
profiles: 不同的profile对应不同的MPD要求和Segment格式要求mediaPresentationDuration:整个节目的时长
minBufferTime: 至少需要缓冲的时间
type:点播对应static,直播对应dynamic
availabilityStartTime=2019-05-22T22:16:57Z
:如果是直播流的话,则必须提供,代表MPD中所有Seg从该时间开始可以request了
minimumUpdatePeriod=PT10H
:至少每隔这么长时间,MPD就有可能更新一次,只用于直播流 -
BaseURL 根目录
该元素可以在MPD\Period\AdaptationSet\Representation同时出现,若同时出现,则层层嵌套;在每一层也可以出现多次,默认使用第一个BaseURL;
3. Period 区段
一条完整的mpeg dash码流可能由一个或多个Period构成,每个Period代表某一个时间段。比如某条码流有60秒时间,Period1从0-15秒,Period2从16秒到40秒,Period3从41秒到60秒。同一个Period内,意味着可用的媒体内容及其各个可用码率(Representation)不会发生变更。直播情况下,“可能”需要周期地去服务器更新MPD文件,服务器可能会移除旧的已经过时的Period,或是添加新的Period。新的Period中可能会添加新的可用码率或去掉上一个Period中存在的某些码率, 即上面的 Representation 字段
属性:
duration:Period的时长;
start:Period的开始时间
4. AdaptationSet 自适应子集
一个Period由一个或者多个Adaptationset组成。Adaptationset由一组可供切换的不同码率的码流(Representation)组成,这些码流中可能包含一个(ISO profile)或者多个(TS profile)media content components,因为ISO profile的mp4或者fmp4 segment中通常只含有一个视频或者音频内容,而TS profile中的TS segment同时含有视频和音频内容. 当同时含有多个media component content时,每个被复用的media content component将被单独描述。
属性:
segmentAlignment: 如果为true,则代表该AS中的segment互不重叠
startWithSAP: 每个Segment的第一帧都是关键帧
mimeType AdaptationSet 的媒体类型
minWidth 最小宽度
par 宽高比
contentType: 内容类型
5. media content component 媒体内容
一个media content component表示表示一个不同的音视频内容,比如不同语言的音轨属于不同的media content component,而同一音轨的不同码率(mpeg dash中叫做Representation)属于相同的media content component。如果是TS profile,同一个码率可能包括多个media content components。
6. SegmentTemplate 片段模板
组成下载 Representation 的URL 模板
属性:
media: 指定用来生成Segment列表的模板,可以包含的通配符有$RepresentaonID$,$Bandwidth$,$Number$, $Time$
7. Representation 媒体文件描述
每个Adaptationset包含了一个或者多个Representations,一个Representation包含一个或者多个media streams,每个media stream对应一个media content component。为了适应不同的网络带宽,dash客户端可能会从一个Representation切换到另外一个Representation
属性:
codecs=avc1.640028
解码器标准
bandwidth=3200000
需要带宽 3.2Mbps
8. segment 切片
每个Representation由一个或者多个segment组成,每个segment由一个对应的URL指定,也可能由相同的URL+不同的byte range指定。dash 客户端可以通过HTTP协议来获取URL(+byte range)对应的分片数据。MPD中描述segment URL的形式有多种,如Segment list,Segment template,Single segment。
单独介绍一个特殊的segment : Initialization Segment(初始化片段),
Representation的Segments一般都采用1个Init Segment+多个普通Segment的方式,还有一种形式就是Self Initialize Segment,这种形式没有单独的Init Segment,初始化信息包括在了各个Segment中。Init Segment中包含了解封装需要的全部信息,比如Representation中有哪些音视频流,各自的编码格式及参数。对于 ISO profile来说(容器为MP4),包含了moov box,H264的sps/pps数据等关键信息存放于此(avCc box)。
切片内容
fMP4(fragmented MP4),可以简单理解为分片化的MP4,是DASH采用的媒体文件格式,文件扩展名通常为(.m4s或直接用.mp4), 或者分别切分成mpa(音频), m4v(视频);
fMP4 由分片组成,可以按整个文件存储,也可以按分片存储:
如果按照单个文件存储,每个输出是一个m4s文件。
完整的fMP4视频可以描述为如下形式:
-
moov + (moof + mdat) * N
-
如果按照分片存储,每个分片是一个m4s文件,输出对应了多个m4s。
fMP4中的第一个分片,对应了DASH协议中Initialization Segment;其后的分片,则对应Media Segment。
注:
-
moov: Movie Box,它是一种container box,子box里包含了媒 体的metadata信息;
-
moof: moofbox,这个box是视频分片的描写叙述信息, 即分片(fragment)的标识
-
mdat: mdatbox 实际媒体数据。我们终于解码播放的数据都在这里面
前端工作
-
加载视频说明mpd文件
-
识别mpd内容
-
判断网速加载第一个适合该网速的视频片段, 解析视频数据
-
视频数据通过 MSE(Media Source Extensions) API 把视频数据传输给Video播放
-
不断通过加载视频片段大小/下载时间得出网速, 下载相应码率的视频
自己动手做DEMO
1. 下载MP4Box(切片工具)
https://gpac.wp.imt.fr/downloads/gpac-nightly-builds/
注: 安装后 application 中的 GPAC是个播放器, 我们需要的是它文件里的下面的MP4Box工具
-
执行命令
sudo /Applications/GPAC.app/Contents/MacOS/MP4Box -dash-strict 5000 -profile dashavc264:live -rap /Users/lijiancheng/Documents/mse/assert/foo.mp4#video /Users/lijiancheng/Documents/mse/assert/foo.mp4#audio -out index.mpd
-
引入Dash.js(开源库)
html
<script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script> -
video src标明地址
html
<video data-dashjs-player autoplay src="./assert/index.mpd" controls></video>
别人的DASH DEMO
http://reference.dashif.org/dash.js/nightly/samples/dash-if-reference-player/index.html
http://demo.theoplayer.com/test-your-stream-with-statistics
https://bitmovin.com/demos/stream-test
DASH 切片工具
-
FFmpeg
-
MP4Box
Dash开源库
-
Dash.js 前端播放
相关文档
-
自适应流媒体传输(四)——深入理解MPD(https://blog.csdn.net/nonmarking/article/details/85714099)
-
MP4Box指令(https://gpac.wp.imt.fr/mp4box/dash/)
-
DASH简介及使用方法(FFmpeg, MP4Box)(https://blog.csdn.net/yue_huang/article/details/78466537)
-
MP4Box的安装和使用(https://www.jianshu.com/p/c801e8dd041e)
-
DASH协议及各种码率自适应协议的对比(https://juejin.im/post/5a697868f265da3e3f4ce17d)
-
Azure 媒体服务支持 DASH 实时传送流(https://blogs.msdn.microsoft.com/azchina/2014/12/04/azure-dash/)
-
第四部分:如何借助当前的自适应比特率技术降低广播延迟 – 参考架构和测试结果(https://aws.amazon.com/cn/blogs/china/compete-broadcast-latency-bitrate-tech4/)