CDN这几年爆炸式增长,带宽提速是根源,而HTTP始终还是那个屌样,因此目前CDN大多是资本性行业,不用多少知识就能干了;直到流媒体粗现,直播咋这么难搞呢?因为它是流媒体,让我带你深入浅出看流媒体前世今生,分分钟二逼变牛逼。
流媒体分为点播和直播,点播已经堕落为HTTP文件了,直播永远不可能只用HTTP就OK,这是他们的业务差异导致的。流媒体本质上是:现实的图像,经过编码器压缩,持久化为点播文件或者直播流,经过传输,在终端解码和展示。
点播为何属于HTTP而不是流媒体呢?点播,譬如电影或者录制的影像,传输给观看的终端时是不变的,一万个人看一个电影无论什么时候看都是一样的媒体数据,因此传输上直接使用HTTP就可以了。点播的流媒体特征还是有的:
点播的重新编码,譬如为不同终端输出不同码率和尺寸的点播文件,需要媒体知识了。这部分因为使用太广泛,所以开源届早就支持得很成熟,ffmpeg对文件重新编码已经做得很好了。
点播P2P,这个实际上分为客户端的P2P和web P2P,这个和媒体没有什么关系,但属于点播需要做的范围,没有现成的方案。(插播广告:观止创想已经支持了点播HLS的P2P,现有系统不用修改就可以加上web P2P)
其他的什么分片,DRM,弹幕,分享,多终端转封装,文件调度,HTTP API调度,热点,mp4/flv-range请求,存储等等。大多都有了成熟的方案,和HTTP文件一样的技术,要么就是播放器支持,这些和流媒体一毛钱关系都没有。
这就是为何CDN支持点播支持得很得心应手,几乎所有的CDN都能直接支持点播分发,甚至一些新兴的行业公司,譬如在线教育,对于点播都能自己搞。点播就是HTTP而已,不属于流媒体范畴。
直播呢,从古老的RTSP到RTMP,HTTP渐进式下载,到HTTP流,到HLS和HDS,到DASH,到私有的websocket。这些不过是直播分发的表象,譬如HTTP直播流就是HTTP点播吗?不是。HTTP点播本质上是文件分发,而HTTP流是流媒体服务器在内存中将直播的包,打包成RTSP、RTMP、HTTP后发送给每个客户端。
当然总有例外的,有一个公司尝试过直播进行点播化,就是时移直播,将直播流录制成点播文件,然后客户端请求时总是请求点播。这种私有协议迟早是要死掉的,只有自己的播放器能播,而且得在CDN上部署自己的流媒体;现在这个公司也放弃了自己的“高大上”的私有协议——互联网的基本精神就是开放标准。可惜中国人很难认同这个理念,牛逼的总喜欢搞私有协议,譬如使用websocket的公司,大多属于这种类型,牛逼的人太多就是这种结果,一般这种公司也很有钱,譬如某上市的做在线秀场的公司。
目前直播分发有几个特点:
偏好flv,少用ts:flv标准11页,ts标准174页。标准文档十倍差异,代码实现起来十倍都不止。因此一般的公司都喜欢flv,pc时代都是flv的天下,什么flv流,flv切片;因为自己写代码支持ts比较麻烦,用ffmpeg的代码又太庞大。直到移动端粗现,现在直播只支持pc的少之又少了,使用flv作为基础结构的产品要么艰难转型,要么就掩耳盗铃说FLV很优雅,HLS太垃圾。
rtmp和hls并存:rtmp一般用于pc-flash播放直播,而hls用于移动端播放。flash能播放hls吗?前年jwplayer就支持了,可惜是商业版不开源;去年有很多开源的as播放器支持hls。而直播系统,特别是cdn的直播,不会更新这么快,pc端还是rtmp系为主。这个特点是由于平台客户端支持的流决定的,并非最佳方案,也不是用户愿意这么干。
实时流大多使用rtmp:实时流,延迟要求在5秒之内的流,大多使用rtmp协议。pc上可以直接播放,移动端就需要使用ffmpeg解码播放。有没有更好的分发方案?实际上http-flv比rtmp更合适,延迟一样,要求服务器支持,pc能直接播,移动端需要使用ffmpeg,还有个好处是能穿墙。为何cdn大多不支持http-flv直播?因为一般的web服务器支持不了,这是个流媒体问题。
rtsp永远死不了:这是监控行业的协议,我们都有门户之见,“RTMP这个烂货怎么还在互联网上用呢?RTSP多么优美!”因此有监控行业背景的公司做互联网业务,都带着门户之见不得已将RTSP转RTMP,而且还要愤愤的说——只不过是不用装个插件而已。
直播的本质特点,就是需要专门的服务器分发,至少需要直播源站切片HLS后分发。也就是直播需要专门的流媒体服务器,目前开源的流媒体,最古老的是RED5,后面是CRTMPD,风生水起的是NGINX-RTMP,目前最新出的是SRS。
为何RED5不能一统天下?RED5和FMS一样古老,先行者如果不能放掉自己的光环,迟迟不肯变革,就会被后来者超越。RED5性能是很差,但并非是因为使用了java的原因,这个看看wowza就知道了,商业服务器wowza虽然是个内存杀手,但是支持的并发一点都不含糊。RED5没有广泛商用的原因可能一直是一个先行者,祖先的角色。软件只有快速变化适应需求才能发展,和年纪没有关系。
那么CRTMPD怎样?牛逼!使用单进程单线程异步socket,这是和nginx同时代的产物。CRTMFPD是有不少铁杆粉丝的,以那个时代开始做直播业务的为主。CRTMDP生不逢时,遇到NGINX了,不少NGINX的粉丝是技术牛逼的人物,不然怎么能看懂void*****呢?除了社区的差异之外,CRTMPD没有支持HLS,倒是支持了RTSP,这就是典型的倒行逆施,互联网上支持RTSP,大约只有CRTMPD能想到了。
NGINX-RTMP风生水起有几个很重要的因素。首先2012年开始CDN业务开始快速增长,随之直播业务也需求暴涨,没有特别满意的流媒体服务器;其次,NGINX在HTTP领域绝对是霸主,大家对于NGINX系的熟悉程度很高,便于维护;再次,直播点播使用一套服务器,很有诱惑力,这可以算是“万金油”效应,很多套服务器搞得焦头烂额,肯定一套服务器能解决问题;最后,CDN是运维比技术牛逼的行业,运维的信心都是运行出来的,NGINX运行那么良好,那么NGINX-RTMP也肯定不错。
SRS粗来了,并非石头缝里蹦粗来个SRS,SRS其实诞生的历史是:第一个版本实际上是参考NGINX,基本上和NGINX-RTMP同时间点做出来;第二版本是改用ST作为基础结构,支持RTMP直播点播;第三版本是从CDN出来后重写的,只支持直播。为何SRS不使用NGINX那种基础结构,这个和google为何开发golang的原因一样。SRS和NGINX-RTMP最重要的区别有两点:其一,使用类似golang的服务器架构;其二,流媒体业务驱动的产品管理,如果可以装装逼,SRS是以流媒体业务为主的服务器,而不是以分发协议为主的服务器。
什么是以流媒体为主?流媒体系统的层次包括:网络层(socket或st)负责传输,协议层(rtmp或http)负责网络打包,封装层(flv、ts、hls、hds、adts、annexb)负责编解码数据的封装,编码层(h.264和aac)负责图像压缩。流媒体服务器的重点在于封装层,譬如flv、ts、hls、hds、adts和annexb的解析和打包都是自己实现的代码,参考标准规范,支持完善的封装转换和解析。而网络层因为使用st简化,使得协议层更简单,错误的概率更低,这个和流媒体的关系就不大了。
什么是以业务为主?“跑起来”和“商用”是两回事情,商用需要对于流媒体的业务有很好的支持:譬如vhost,这个是计费才有的概念,基于app的也能计费,结果就是要求用户不能app重复,新增app需要联系运维,凡是添加app需要联系运维的cdn,肯定是NGINX-RTMP;譬如日志,出现问题能将流媒体的整个链条的日志都能找出来,从边缘到回源链接,到上层节点的日志,一直追溯到推流连接的日志,每个日志都是基于连接的;譬如rtmp+http-flv+hls,国内主要的直播业务都能支持,还有hds可以供那些想装逼的客户用;更多牛逼的业务功能就不啰嗦了。
对于流媒体服务器,除非能忘记HTTP服务器,才能看清楚到底为何流媒体和HTTP没有一毛钱关系,而流媒体在于团队对于流媒体和服务器的理解,而并非找到一个万金油服务器能涂抹掉客户问题。
直播这么多协议,这多么服务器,当前直播重心在哪里?该如何选择合适的协议?只要问自己三个问题就可以了:
延迟要求,是否要求低于5秒的延迟?如果是硬指标,就只能选择RTMP或HTTP-FLV流。移动端需要自己编译FFMPEG支持,无法直接播放。
终端适配,是否要求支持PC和移动端(IOS和Android)?如果需要广泛支持移动端,HLS是最好的选择。
节约带宽,是否要求支持WebP2P?如果需要支持FlashP2P,或者移动端P2P,选择HLS。
当初有个跨国老牌的流媒体公司,劝说不要使用RTMP了,因为半年时间RTMP就会死掉,DASH会替代所有的流媒体协议。现在2年过去了,RTMP和HLS除了更加爆炸性应用之外,我看死掉的是那些过于技术至上的公司。
如果用一句话说流媒体直播:实时性要求高的用RTMP或HTTP-FLV,其他都用HLS。
协议请参考:https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DeliveryHLS
服务器请参考:https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Compare
关于SRS的架构参考:https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Architecture