年后着手Node版本EasyDarwin的开发工做,截止到今天2018年03月27日上线了第一个版本,今天小米发布了MIX2S, 致敬! 致敬!html
目前这个初版暂时仅支持RTSP Over TCP, 不过RTSP Over UDP也会很快实现.整体来讲, RTSP协议比较简单.开发过程当中对RTSP协议的理解主要参考了 rtsp协议详解 这篇文章.sdp的解析一开始本身写的, 反复参考资料了解sdp各个字段的含义.后来偶然在npm上找到 sdp-transform 这个库, 处理sdp信息很是方便, 果断star了.git
记录sdp两个细节的地方:github
m
媒体描述下面有个属性名为 control
的属性, 它的值和后续 SETUP
请求的 uri
的尾巴是对应的, 椐此能够明确 SETUP
是音频仍是视频.web
SETUP
携带的请求头 Transport
中有个参数叫 interleaved
, 这个东西常见的内容是一个偶数-一个奇数
, 这两个数值表明RTP传输的通道标识
.一个RTP包前面有4个节字的头: 1个字节的固定$(0x24)符;1个字节通道标识;2个字节的RTP包长度.对应的正是这个头里面的第2个字节.通常偶数表示数据通道, 奇数表示控制通道.npm
理解以上两点, 有助于在RTP传输过程当中, 针对特定的视频格式, 缓存GOP,实现秒开效果.缓存
从TCP流式数据中解析RTP包, 对NodeJS的处理效率是个考验.在初始阶段, 简单的利用 socket data 事件回调, 只要接收到数据, 就走一次协议解析. 实测发现一路播放的状况下都很卡顿. 最后是参考了 Node-Media-Server 中的 BufferPool 实现, 利用 Generator 和 yield. 只有当接收数据长度达到要求的时候, 才去作协议解析. 这样效率获得巨大提高, 播放不卡顿了. 中间还尝试过利用 socket pipe 将RTP包流转给播放端, 这样作确实效率很高, 也能够解决播放卡顿. 可是这种方式下, 解不到单个RTP包, 就没法作GOP缓存, 因此弃用了.服务器
结合sdp中的媒体描述和 SETUP Transport interleaved 的值, 能够识别出一个RTP包携带的内容是媒体数据仍是控制数据, 若是是媒体数据, 是音频仍是视频, 若是是视频, 那么视频数据的编码格式是什么. 基于这些, 当收到携带h264数据的RTP包时, 作关键帧识别, 缓存GOP.网络
在RTP包中识别h264关键帧, 须要了解RTP包格式, h264 nalu type, fu-a 分包这些内容.这里我主要参考了CSDN上这篇博客 RTP协议全解析(H264码流和PS流)socket
用Node实现EasyDarwin那样的RTSP流媒体转发, 最后的效果是使人满意的.目前的代码量很小.Node在处理字节流的过程当中, 反复使用了自带的Buffer库函数. concat, slice, readXXXBE(以大端方式读网络字节序). 在这一版中, 我给它搭配了一个 HTTP Server, 提供了可视化的统计信息展现. 总之, Node.js 的引入将大大提升EasyDarwin开源流媒体服务的开发效率, 提高EasyDarwin的易用性.svg
EasyDarwin开源流媒体服务器:www.EasyDarwin.org
EasyDSS商用流媒体解决方案:www.EasyDSS.com
EasyNVR无插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2019