H5直播系列四 RTMP HTTP-FLV HLS MPEG-DASH

96
合肥懒皮
0.7 2017.05.03 16:33* 字数 4124

参考
【腾讯Bugly干货分享】从0到1打造直播 App
从入门到出家:流媒体协议—FLV
H5直播起航
全面进阶 H5 直播
HTML5 视频直播(一)HLS 和 RTMP
HTML5 视频直播(二)Web Sockets+Canvas
HTML5 视频直播(三)WebRTC
直播服务器简单实现 http_flv和hls 内网直播桌面
RTMP、RTSP、HTTP视频协议详解(附:直播流地址、播放软件)
带你吃透RTMP
[总结]RTMP流媒体技术零基础学习方法
直播云解决方案整理
直播未来属于RTMP还是HTTP?

Paste_Image.png

一、HLS

HLS (HTTP Live Streaming), 是由 Apple 公司实现的基于 HTTP 的媒体流传输协议。Apple 的全系列产品支持,由于 HLS 是苹果提出的, 所以在 Apple 的全系列产品包括 iphone、 ipad、safari 都不需要安装任何插件就可以原生支持播放 HLS, 现在Android 也加入了对 HLS 的支持。但PC端目前除了Microsoft Edge外,Chrome、Firefox等浏览器均不支持该协议的播放。可直接采用网上一些比较成熟的方案,如:sewise-player、MediaElement、videojs-contrib-hls、jwplayer。

对于支持 HLS 的浏览器来说,直接这样写就能播放了:

<video controls autoplay>  
    <source src="http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8"
 type="application/vnd.apple.mpegurl" />  
    <p class="warning">Your browser does not support HTML5 video.</p>  
</video>

以上测试地址参考 m3u8直播测试地址,或者APPLE提供测试地址

HLS 的基本原理就是当采集推流端将视频流推送到流媒体服务器时,服务器将收到的流信息每缓存一段时间就封包成一个新的 ts 文件,同时服务器会建立一个 m3u8 的索引文件来维护最新几个 ts 片段的索引。当播放端获取直播时,它是从 m3u8 索引文件获取最新的 ts 视频文件片段来播放,从而保证用户在任何时候连接进来时都会看到较新的内容,实现近似直播的体验。相对于常见的流媒体直播协议,例如 RTMP 协议、RTSP 协议等,HLS 最大的不同在于直播客户端获取到的并不是一个完整的数据流,而是连续的、短时长的媒体文件,客户端不断的下载并播放这些小文件。这种方式的理论最小延时为一个 ts 文件的时长,一般情况为 2-3 个 ts 文件的时长。HLS 的分段策略,基本上推荐是 10 秒一个分片,这就看出了 HLS 的缺点:

  • 通常 HLS 直播延时会达到 20-30s,而高延时对于需要实时互动体验的直播来说是不可接受的
  • HLS 基于短连接 HTTP,HTTP 是基于 TCP 的,这就意味着 HLS 需要不断地与服务器建立连接,TCP 每次建立连接时的三次握手、慢启动过程、断开连接时的四次挥手都会产生消耗。

不过 HLS 也有它的优点:

  • 数据通过 HTTP 协议传输,所以采用 HLS 时不用考虑防火墙或者代理的问题。
  • 使用短时长的分片文件来播放,客户端可以平滑的切换码率,以适应不同带宽条件下的播放。
  • HLS 是苹果推出的流媒体协议,在 iOS 平台上可以获得天然的支持,采用系统提供的 AVPlayer 就能直接播放,不用自己开发播放器。
  • HLS有一个非常大的优点:HTML5可以直接打开播放;这个意味着可以把一个直播链接通过微信等转发分享,不需要安装任何独立的APP,有浏览器即可,所以流行度很高。社交直播APP,HLS可以说是刚需

以下参考直播协议 HTTP-FLV 详解
这里首先要说一下,HLS其实是一个“文本协议”,而并不是一个流媒体协议。那么,什么样的协议才能称之为流媒体协议呢?
流(stream): 数据在网络上按时间先后次序传输和播放的连续音/视频数据流。之所以可以按照顺序传输和播放连续是因为在类似 RTMP,FLV协议中, 每一个音视频数据都被封装成了包含时间戳信息头的数据包。而当播放器拿到这些数据包解包的时候能够根据时间戳信息把这些音视频数据和之前到达的音视频数据连续起来播放。MP4,MKV等等类似这种封装,必须拿到完整的音视频文件才能播放,因为里面的单个音视频数据块不带有时间戳信息,播放器不能将这些没有时间戳信息数据块连续起来,所以就不能实时的解码播放。

二、MPEG DASH(Dynamic Adaptive Streaming over HTTP)

参考
MPEG-DASH 流媒体技术介绍(上)
MPEG-DASH 流媒体技术介绍(中)
MPEG-DASH 流媒体技术介绍(下)
MPEG DASH 和 HLS

1.在基于HTTP提供流媒体的方面,到目前为止已经看到了三种方案,苹果的HLS,Adobe HTTP Dynamic Streaming (HDS)和Microsoft Smooth Streaming (MSS),当然,各家用的协议,格式神马的都不会一样。于是每次做支持都要来三人份的。看到这三倍工作量,再想想老板不给加工资,码农们的心都寒了...MPEG的同志们体察到了这份疾苦,呼吁大家来个标准点的玩意呗,于是就有了MPEG DASH这里有一篇综述,写的比我好还图文并茂的,去那看吧~

2.B站在2018.8.2发布的我们为什么使用DASH中提到以后点播会使用DASH方案,直播因为延迟问题仍然使用FLV(评论回复中有提到)

文中有提到B站二压,这个可以参考【教程向】教你怎样压制出“B站直传“的清晰视频

DASH,又叫MPEG DASH,DASH:Dynamic Adaptive Streaming over HTTP ,是一种在互联网上传送动态码率的Video Streaming技术,类似于苹果的HLS,DASH会通过media presentation description (MPD)将视频内容切片成一个很短的文件片段,每个切片都有多个不同的码率,DASH Client可以根据网络的情况选择一个码率进行播放,支持在不同码率之间无缝切换。YouTube采用DASH。其网页端及移动端APP都使用了DASH。DASH的其他采用者包括:Netflix, Hulu。

DASH是由MPEG (Moving Picture Experts Group)组织制定,2010年开始启动,2011年11月发布Draft版本,2012年4月发布第一稿Version(ISO/IEC 23009-1:2012),2014年5月发布第二稿(ISO/IEC 23009-1:2014),最新稿(ISO/IEC 23009-3:2015)。

目前3GPP Release 10已经将DASH纳入其中;在HbbTV 1.5中也支持DASH;DVB-DASH也将DASH纳入到DVB(ETSI TS 103 285 v.1.1.1)。目前DASH Industry Forum由发起厂家组成,致力于推进DASH产品生态,将DASH产业化和业界最佳实践推向批量应用。

15年的B站我们使用整段的FLV和MP4,这种方案的好处是简单且兼容性高,抖音与今日头条就是用该方案。但缺点也很明显,随着视频时长的增长,整段的MP4的头部过于复杂,体积过于庞大,导致拉取与加载极为缓慢。

16年的B站为了规避这个问题,使用了分段的FLV来提升加载速度,这种方案的好处是视频头部小,加载速度高。爱奇艺和优酷也使用类似方案。这种方案简单且兼容性高,而且与直播流统一了格式,所以一直沿用至今,中间由于flv.js的出现 ,把这种方案带向了全平台。

但随着用户的增加,用户的网络种类和情况也变得更加复杂,如果我们需要在各种场景下都需要给用户较好的体验,我们需要选择一种能在不同网络下都能流畅播放的方案。我们需要引入Dynamic Adaptive Streaming/ Bitrate 技术,以进一步提升用户体验。我们也需要对多音轨和多视频轨

在评估了一些行业内使用的方案后,我们选中了DASH,DASH也可以更灵活的实现用户与产品的新增需求。


image.png

image.png

对于普通看视频的用户,我们期待部署Dash有以下改进:

  • 观看视频更为流畅,如下图所示,我们会在网速不佳时无缝切换至较低清晰度视频,在网速充足时无缝切换至高清晰度视频,切换过程对于用户无感。
  • 可以很容易的支持音频模式,满足听相声/音乐的你
  • 在退到后台后,可以自动切换至只拉取音频,更节省你的流量,播放更加流畅。(恢复回来可能黑屏,所以上传视频时,会做GOP对齐,并尝试将GOP缩减到5s)
  • 可以很容易的支持视频新增多音轨,多视频轨,多字幕轨的任意切换 ,原声,中配,多版本字幕任君选择。

3.兼容性
参考
新时代的点播与直播
wikipedia DASH
Why YouTube & Netflix use MPEG-DASH in HTML5

MSE(Media Source Extensions)是目前Youtube使用的DASH的基础。

image.png

dash.js是Dash行业论坛官方参考和生产播放器。
shaka-player是出自Google的开源dash播放器。

三、RTMP

RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。

使用RTMP技术的流媒体系统有一个非常明显的特点:使用 Flash Player 作为播放器客户端,而Flash Player 现在已经安装在了全世界将近99%的PC上,因此一般情况下收看RTMP流媒体系统的视音频是不需要安装插件的。用户只需要打开网页,就可以直接收看流媒体,十分方便。

相对于 HLS 来说,采用 RTMP 协议时,从采集推流端到流媒体服务器再到播放端是一条数据流,因此在服务器不会有落地文件。这样 RTMP 相对来说就有这些优点:

  • 延时较小,通常为 1-3s。
  • 基于 TCP 长连接,不需要多次建连。

因此业界大部分直播业务都会选择用 RTMP 作为流媒体协议。通常会将数据流封装成 FLV 通过 HTTP 提供出去。但是这样也有一些问题需要解决:

Paste_Image.png
       public function simplest_as3_rtmp_player()
        {
            nc = new NetConnection();
            nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
            nc.connect("rtmp://localhost/live");
        }
        private function netStatusHandler(event:NetStatusEvent):void
        {
          trace("event.info.level: " + event.info.level + "\n", 
          "event.info.code: " + event.info.code);
            switch (event.info.code)
            {
                case "NetConnection.Connect.Success":
                    doVideo(nc);
                    break;
                case "NetConnection.Connect.Failed":
                    break;
                case "NetConnection.Connect.Rejected":
                    break;
                case "NetStream.Play.Stop":
                    break;
                case "NetStream.Play.StreamNotFound":
                    break;
            }
        }
        // play a recorded stream on the server
        private function doVideo(nc:NetConnection):void {
            ns = new NetStream(nc);
            ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);

            video = new Video(640,480);
            video.attachNetStream(ns);

            ns.play("myCamera");
            addChild(video);
        }
四、HTTP-FLV协议:

即使用HTTP协议流式的传输媒体内容。相对于RTMP,HTTP更简单和广为人知,而且不担心被Adobe的专利绑架。内容延迟同样可以做到2~5秒,打开速度更快,因为HTTP本身没有复杂的状态交互。所以从延迟角度来看,HTTP-FLV要优于RTMP。

http_flv&rtmp这两个协议实际上传输数据是一样的,数据都是flv文件的tag。http_flv是一个无限大的http流的文件,相比rtmp就只能直播,而rtmp还可以推流和更多的操作。但是http有个好处,就是是以80http通信的,穿透性强,而且rtmp是非开放协议。这两个协议是如今直播平台主选的直播方式,主要原因就是延时极低。

以下参考直播http-flv小调研
HTTP协议中有个约定:content-length字段,http的body部分的长度
服务器回复http请求的时候如果有这个字段,客户端就接收这个长度的数据然后就认为数据传输完成了,如果服务器回复http请求中没有这个字段,客户端就一直接收数据,直到服务器跟客户端的socket连接断开。

http-flv直播就是利用第二个原理,服务器回复客户端请求的时候不加content-length字段,在回复了http内容之后,紧接着发送flv数据,客户端就一直接收数据了。

五、其它

1.直播整体流程大致可分为:

  • 视频采集端:可以是电脑上的音视频输入设备、或手机端的摄像头、或麦克风,目前以移动端手机视频为主。
  • 直播流视频服务端:一台Nginx服务器,采集视频录制端传输的视频流(H264/ACC编码),由服务器端进行解析编码,推送RTMP/HLS格式视频流至视频播放端。
  • 视频播放端:可以是电脑上的播放器(QuickTime Player、VLC),手机端的native播放器,还有就是 H5 的video标签等,目前还是以手机端的native播放器为主。

2.以下参考基于rtmp协议等的流媒体服务器是否可以被取代
flash已经死了,但是在手机平台上还是有很多人用C++来解析rtmp协议做直播流。因为对比其他直播流协议,rtmp的实时延迟可以做到1秒以内。hls的延迟基本有10秒左右。几年前,我做过一个菲律宾赌场的直播APP,赌场的荷官发牌,然后客户端同时显示开牌信息,如果不同步或者超过1秒内的延迟,会给用户一种作弊的感觉。使用rtmp,就算在美国看这个直播,延迟也是在1秒以内。找了很多视频直播协议,实时性最好就是rtmp,暂时找不到能代替rtmp的协议。
3.以下参考前主流视频网站视频点播都是使用的哪些协议
几乎所有主流直播平台网站几乎都是主线路为cdn提供的httpflv,其他线路大部分都是rtmp。上面有人说httpflv的延迟比rtmp高一点,那是瞎扯,httpflv理论延时至少是与rtmp差不多的。至于HLS,我以前倒是在web上见到过,只不过现在没见到了,几乎都是rtmp+httpflv。至于hls相对rtmp及httpflv的优点,我想仅仅是能够html5播放,仅此而已,hls本身有很多不好的设计,比如ts文件,ts文件是不停的在http请求,这就相当于http和长连接的区别,不仅带来服务器的资源消耗,还有http报文头一堆冗余信息。这对流媒体直播那金贵流量费来说,这不不是一个好选择。hls还有个致命的问题,那就是延时,本身就是分文件块传输的,延时自然比rtmp高出许多。如果将hls的ts文件缩小,或许稍许降低延时。但hsl真的不是面向大众直播的第一选择。

视频直播