RTMP(Real-Time Messaging Protocol,实时消息传输协议)是Adobe开发的一种用于实时数据通信的应用层网络协议,基于TCP传输。实际上是一个协议族,主协议是RTMP,包括RTMP基本协议及RTMPT/RTMPS/RTMPE/RTMFP等多种变种,其中RTMFP是RTMP基于UDP传输的一种协议,用于P2P通信。该协议主要用于解决多媒体数据传输流中的多路复用和分包问题。
目前国内RTMP协议主要用于直播推流端,在播放端的使用非常少。虽然RTMP是封闭协议,但实际上rtmpdump的开源库已经基本实现了这个协议,基于该开源项目进行二次开发,可以减少绝大部分工作量。相较于RTP协议,用RTMP推流时无论客户端还是服务端的开发工作都较为简单,在使用过程中也较为易于理解,可靠性更高但延迟会相对高一点。(建议快速上线使用RTMP,超低延迟直播或长远考虑用RTP)
RTMP协议中的分块(Chunk)可以用来实现流多路复用和分包,其中块大小是可以设置的。显然,将消息分块传输会带来额外开销,所以需要尽可能减少额外开销。块越小可能开销越大,块越大可能延迟越大(某些重要优先级的消息到达也缓慢)
Web端推流,目前能想到的就是在浏览器已经有flash插件的情况下,直接调用flash推流
移动端推流可以使用rtmp库。Android端的音视频数据编码、封装如果在上层的话,需要通过JNI来调用rtmp库的接口;ios端OC可以和该库中的C语言直接混编调用
rtmp推流过程中,很容易出现延迟较大的情况(虽然名字上叫实时协议,但延迟高达10s不是梦啊……)。这主要来源于两部分——网络抖动和TCP重传(实际上工程应用中,还有音视频采集和编码模块的不稳定性、硬件设备受限等各种因素)。
RTMP协议内部以及rtmp库本身都没有适应网络抖动的策略,所以推流过程中,需要开发人员自己去增加这部分策略。若使用原生的协议和开源库,当带宽受限时数据包会累积在“待发送缓冲区”,延迟逐步增大。而且即使客户端上行带宽一直较为稳定,由于TCP传输的可靠性,总会有一些数据包重传,累积延迟进一步增大。这部分的优化可以考虑在推流端加入丢帧策略(千万注意不要导致花屏和跳播),加入带宽评估模块,在服务端优化网络环境,使用BGP机房,就近节点推流等。
RTMP默认的超时时间是比较长的,在实际应用场景中一般无法忍受。同样需要开发人员根据业务需求,修改配置并优化重连策略。
主要是针对移动网络下网络断开、延迟过大等情况,需要开发人员按需重连。
对于直播播放来说,音视频的流畅也尤为重要。在推流过程中的任意一个环节导致的音视频数据没有及时存储到源服务器(或分发到CDN节点),都会从源头上导致播放不流畅。
很显然我们无法要求网络一直稳定,也不敢说服务端的接收和分发就完全可靠,能做的只是尽可能减少副作用。如果是对延迟不太敏感的直播,最好的办法当然就是设立缓冲;如果是延迟比较敏感的直播,可以用抖动缓冲区,不断在延迟和流畅度之间找平衡;如果是延迟极为敏感的直播,建议直接要求推流用户自身保障设备在高速网络下不挪动,或者换协议。在源流服务器和CDN分发部分,可以使用BGP机房,多机房及多CDN厂商之间调度。